void CALLBACK_Init(Section* /*sec*/) { Bitu i; for (i=0;i<CB_MAX;i++) { CallBack_Handlers[i]=&illegal_handler; } /* Setup the Stop Handler */ call_stop=CALLBACK_Allocate(); CallBack_Handlers[call_stop]=stop_handler; CALLBACK_SetDescription(call_stop,"stop"); phys_writeb(CALLBACK_PhysPointer(call_stop)+0,0xFE); phys_writeb(CALLBACK_PhysPointer(call_stop)+1,0x38); phys_writew(CALLBACK_PhysPointer(call_stop)+2,(Bit16u)call_stop); /* Setup the idle handler */ call_idle=CALLBACK_Allocate(); CallBack_Handlers[call_idle]=stop_handler; CALLBACK_SetDescription(call_idle,"idle"); for (i=0;i<=11;i++) phys_writeb(CALLBACK_PhysPointer(call_idle)+i,0x90); phys_writeb(CALLBACK_PhysPointer(call_idle)+12,0xFE); phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38); phys_writew(CALLBACK_PhysPointer(call_idle)+14,(Bit16u)call_idle); /* Default handlers for unhandled interrupts that have to be non-null */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); call_default2=CALLBACK_Allocate(); CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default"); /* Only setup default handler for first part of interrupt table */ for (Bit16u ct=0;ct<0x60;ct++) { real_writed(0,ct*4,CALLBACK_RealPointer(call_default)); } for (Bit16u ct=0x68;ct<0x70;ct++) { real_writed(0,ct*4,CALLBACK_RealPointer(call_default)); } /* Setup block of 0xCD 0xxx instructions */ PhysPt rint_base=CALLBACK_GetBase()+CB_MAX*CB_SIZE; for (i=0;i<=0xff;i++) { phys_writeb(rint_base,0xCD); phys_writeb(rint_base+1,(Bit8u)i); phys_writeb(rint_base+2,0xFE); phys_writeb(rint_base+3,0x38); phys_writew(rint_base+4,(Bit16u)call_stop); rint_base+=6; } // setup a few interrupt handlers that point to bios IRETs by default real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x68*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff //real_writed(0,0xf*4,0); some games don't like it call_priv_io=CALLBACK_Allocate(); // virtualizable in-out opcodes phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x00,(Bit8u)0xec); // in al, dx phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x01,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x02,(Bit8u)0xed); // in ax, dx phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x03,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x04,(Bit8u)0x66); // in eax, dx phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x05,(Bit8u)0xed); phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x06,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x08,(Bit8u)0xee); // out dx, al phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x09,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0a,(Bit8u)0xef); // out dx, ax phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0b,(Bit8u)0xcb); // retf phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0c,(Bit8u)0x66); // out dx, eax phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0d,(Bit8u)0xef); phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0e,(Bit8u)0xcb); // retf }
void CALLBACK_Init() { for (Bitu i = 0; i < CB_MAX; i++) CallBack_Handlers[i] = &illegal_handler; // Setup the Stop Handler call_stop = CALLBACK_Allocate(); CallBack_Handlers[call_stop] = stop_handler; CALLBACK_SetDescription(call_stop, "stop"); vPC_aStosw(CALLBACK_PhysPointer(call_stop)+0, 0x38FE); // GRP 4 + Extra Callback instruction vPC_aStosw(CALLBACK_PhysPointer(call_stop)+2, (Bit16u)call_stop); // Setup the idle handler call_idle = CALLBACK_Allocate(); CallBack_Handlers[call_idle] = stop_handler; CALLBACK_SetDescription(call_idle, "idle"); for (Bitu i = 0; i <= 11; i++) vPC_aStosb(CALLBACK_PhysPointer(call_idle)+i, 0x90); // NOP vPC_aStosw(CALLBACK_PhysPointer(call_idle)+12, 0x38FE); // GRP 4 + Extra Callback instruction vPC_aStosw(CALLBACK_PhysPointer(call_idle)+14, (Bit16u)call_idle); // Default handlers for unhandled interrupts that have to be non-null call_default = CALLBACK_Allocate(); CALLBACK_Setup(call_default, &default_handler, CB_IRET, "default"); call_default2 = CALLBACK_Allocate(); CALLBACK_Setup(call_default2, &default_handler, CB_IRET, "default"); // Only setup default handler for first part of interrupt table for (Bit16u ct = 0; ct < 0x60; ct++) vPC_rStosd(ct*4, CALLBACK_RealPointer(call_default)); for (Bit16u ct = 0x68; ct < 0x70; ct++) vPC_rStosd(ct*4, CALLBACK_RealPointer(call_default)); // Setup block of 0xCD 0xxx instructions PhysPt rint_base = CALLBACK_GetBase()+CB_MAX*CB_SIZE; for (Bitu i = 0; i <= 0xff; i++) { vPC_aStosb(rint_base, 0xCD); vPC_aStosb(rint_base+1, (Bit8u)i); vPC_aStosw(rint_base+2, 0x38FE); // GRP 4 + Extra Callback instruction vPC_aStosw(rint_base+4, (Bit16u)call_stop); rint_base += 6; } // setup a few interrupt handlers that point to bios IRETs by default vPC_rStosd(0x0e*4, CALLBACK_RealPointer(call_default2)); // design your own railroad vPC_rStosd(0x66*4, CALLBACK_RealPointer(call_default)); // war2d vPC_rStosd(0x67*4, CALLBACK_RealPointer(call_default)); vPC_rStosd(0x68*4, CALLBACK_RealPointer(call_default)); vPC_rStosd(0x5c*4, CALLBACK_RealPointer(call_default)); // Network stuff // virtualizable in-out opcodes call_priv_io = CALLBACK_Allocate(); vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x00, 0xcbec); // in al, dx + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x02, 0xcbed); // in ax, dx + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x04, 0xed66); // in eax, dx vPC_aStosb(CALLBACK_PhysPointer(call_priv_io)+0x06, (Bit8u)0xcb); // retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x08, 0xcbee); // out dx, al + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x0a, 0xcbef); // out dx, ax + retf vPC_aStosw(CALLBACK_PhysPointer(call_priv_io)+0x0c, 0xef66); // out dx, eax vPC_aStosb(CALLBACK_PhysPointer(call_priv_io)+0x0e, (Bit8u)0xcb); // retf }