move force vm86 I/O init to bios stage

This commit is contained in:
Jonathan Campbell 2013-10-26 13:33:18 -07:00
parent e624ccc2ff
commit db5ef7de40
3 changed files with 37 additions and 10 deletions

View File

@ -140,6 +140,7 @@ bool CPU_IO_Exception(Bitu port,Bitu size);
void CPU_RunException(void); void CPU_RunException(void);
void CPU_ENTER(bool use32,Bitu bytes,Bitu level); void CPU_ENTER(bool use32,Bitu bytes,Bitu level);
void init_vm86_fake_io();
#define CPU_INT_SOFTWARE 0x1 #define CPU_INT_SOFTWARE 0x1
#define CPU_INT_EXCEPTION 0x2 #define CPU_INT_EXCEPTION 0x2

View File

@ -2580,7 +2580,7 @@ static Bitu vm86_fake_io_seg = 0xF000; /* unused area in BIOS for IO instruction
static Bitu vm86_fake_io_off = 0x0700; static Bitu vm86_fake_io_off = 0x0700;
static Bitu vm86_fake_io_offs[3*2]={0}; /* offsets from base off because of dynamic core cache */ static Bitu vm86_fake_io_offs[3*2]={0}; /* offsets from base off because of dynamic core cache */
static void init_vm86_fake_io() { void init_vm86_fake_io() {
Bitu phys = (vm86_fake_io_seg << 4) + vm86_fake_io_off; Bitu phys = (vm86_fake_io_seg << 4) + vm86_fake_io_off;
Bitu wo = 0; Bitu wo = 0;
@ -2628,8 +2628,6 @@ Bitu CPU_ForceV86FakeIO_In(Bitu port,Bitu len) {
static const char suffix[4] = {'B','W','?','D'}; static const char suffix[4] = {'B','W','?','D'};
Bitu old_ax,old_dx,ret; Bitu old_ax,old_dx,ret;
init_vm86_fake_io();
/* save EAX:EDX and setup DX for IN instruction */ /* save EAX:EDX and setup DX for IN instruction */
old_ax = reg_eax; old_ax = reg_eax;
old_dx = reg_edx; old_dx = reg_edx;
@ -2637,8 +2635,8 @@ Bitu CPU_ForceV86FakeIO_In(Bitu port,Bitu len) {
reg_edx = port; reg_edx = port;
/* DEBUG */ /* DEBUG */
fprintf(stderr,"CPU virtual 8086 mode: Forcing CPU to execute 'IN%c 0x%04x so OS can trap it. ",suffix[len-1],port); // fprintf(stderr,"CPU virtual 8086 mode: Forcing CPU to execute 'IN%c 0x%04x so OS can trap it. ",suffix[len-1],port);
fflush(stderr); // fflush(stderr);
/* make the CPU execute that instruction */ /* make the CPU execute that instruction */
CALLBACK_RunRealFar(vm86_fake_io_seg,vm86_fake_io_offs[(len==4?2:(len-1))+0]); CALLBACK_RunRealFar(vm86_fake_io_seg,vm86_fake_io_offs[(len==4?2:(len-1))+0]);
@ -2647,7 +2645,7 @@ Bitu CPU_ForceV86FakeIO_In(Bitu port,Bitu len) {
ret = reg_eax; ret = reg_eax;
if (len == 1) ret &= 0xFF; if (len == 1) ret &= 0xFF;
else if (len == 2) ret &= 0xFFFF; else if (len == 2) ret &= 0xFFFF;
fprintf(stderr," => v86 result 0x%02x\n",ret); // fprintf(stderr," => v86 result 0x%02x\n",ret);
/* then restore EAX:EDX */ /* then restore EAX:EDX */
reg_eax = old_ax; reg_eax = old_ax;
@ -2660,8 +2658,6 @@ void CPU_ForceV86FakeIO_Out(Bitu port,Bitu val,Bitu len) {
static const char suffix[4] = {'B','W','?','D'}; static const char suffix[4] = {'B','W','?','D'};
Bitu old_ax,old_dx; Bitu old_ax,old_dx;
init_vm86_fake_io();
/* save EAX:EDX and setup DX/AX for OUT instruction */ /* save EAX:EDX and setup DX/AX for OUT instruction */
old_ax = reg_eax; old_ax = reg_eax;
old_dx = reg_edx; old_dx = reg_edx;
@ -2670,7 +2666,7 @@ void CPU_ForceV86FakeIO_Out(Bitu port,Bitu val,Bitu len) {
reg_eax = val; reg_eax = val;
/* DEBUG */ /* DEBUG */
fprintf(stderr,"CPU virtual 8086 mode: Forcing CPU to execute 'OUT%c 0x%04x,0x%02x so OS can trap it.\n",suffix[len-1],port,val); // fprintf(stderr,"CPU virtual 8086 mode: Forcing CPU to execute 'OUT%c 0x%04x,0x%02x so OS can trap it.\n",suffix[len-1],port,val);
/* make the CPU execute that instruction */ /* make the CPU execute that instruction */
CALLBACK_RunRealFar(vm86_fake_io_seg,vm86_fake_io_offs[(len==4?2:(len-1))+3]); CALLBACK_RunRealFar(vm86_fake_io_seg,vm86_fake_io_offs[(len==4?2:(len-1))+3]);

View File

@ -2045,6 +2045,16 @@ static Bitu INT15_Handler(void) {
void restart_program(std::vector<std::string> & parameters); void restart_program(std::vector<std::string> & parameters);
static Bitu IRQ14_Dummy(void) {
/* FIXME: That's it? Don't I EOI the PIC? */
return CBRET_NONE;
}
static Bitu IRQ15_Dummy(void) {
/* FIXME: That's it? Don't I EOI the PIC? */
return CBRET_NONE;
}
static Bitu Reboot_Handler(void) { static Bitu Reboot_Handler(void) {
// switch to text mode, notify user (let's hope INT10 still works) // switch to text mode, notify user (let's hope INT10 still works)
const char* const text = "\n\n Restart requested by application."; const char* const text = "\n\n Restart requested by application.";
@ -2101,7 +2111,7 @@ static unsigned char do_isapnp_chksum(unsigned char *d,int i) {
class BIOS:public Module_base{ class BIOS:public Module_base{
private: private:
CALLBACK_HandlerObject callback[11]; CALLBACK_HandlerObject callback[13];
public: public:
BIOS(Section* configuration):Module_base(configuration){ BIOS(Section* configuration):Module_base(configuration){
/* tandy DAC can be requested in tandy_sound.cpp by initializing this field */ /* tandy DAC can be requested in tandy_sound.cpp by initializing this field */
@ -2196,6 +2206,26 @@ public:
// We don't handle it, so use the reboot function as exit. // We don't handle it, so use the reboot function as exit.
RealSetVec(0x19,rptr); RealSetVec(0x19,rptr);
// INT 7Eh: IDE IRQ 14
// This is just a dummy IRQ handler to prevent crashes when
// IDE emulation fires the IRQ and OS's like Win95 expect
// the BIOS to handle the interrupt.
callback[11].Install(&IRQ14_Dummy,CB_IRET,"irq 14 ide");
callback[11].Set_RealVec(0x7E);
rptr = callback[11].Get_RealPointer();
phys_writeb(((rptr>>16)<<4)+(rptr&0xFFFF),0xCF); /* IRET */
// INT 7Fh: IDE IRQ 15
// This is just a dummy IRQ handler to prevent crashes when
// IDE emulation fires the IRQ and OS's like Win95 expect
// the BIOS to handle the interrupt.
callback[12].Install(&IRQ15_Dummy,CB_IRET,"irq 15 ide");
callback[12].Set_RealVec(0x7F);
rptr = callback[12].Get_RealPointer();
phys_writeb(((rptr>>16)<<4)+(rptr&0xFFFF),0xCF); /* IRET */
init_vm86_fake_io();
// The farjump at the processor reset entry point (jumps to POST routine) // The farjump at the processor reset entry point (jumps to POST routine)
phys_writeb(0xFFFF0,0xEA); // FARJMP phys_writeb(0xFFFF0,0xEA); // FARJMP
phys_writew(0xFFFF1,RealOff(BIOS_DEFAULT_RESET_LOCATION)); // offset phys_writew(0xFFFF1,RealOff(BIOS_DEFAULT_RESET_LOCATION)); // offset