diff --git a/include/callback.h b/include/callback.h index dab0609d..1056e620 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.17 2006-04-22 15:25:44 c2woody Exp $ */ +/* $Id: callback.h,v 1.18 2006-07-24 19:06:55 c2woody Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -28,22 +28,29 @@ typedef Bitu (*CallBack_Handler)(void); extern CallBack_Handler CallBack_Handlers[]; -enum { CB_RETN,CB_RETF,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,CB_HOOKABLE }; +enum { CB_RETN,CB_RETF,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, + CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR, + CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET }; -#define CB_MAX 144 +#define CB_MAX 128 +#define CB_SIZE 32 #define CB_SEG 0xF100 -#define CB_BASE (CB_SEG << 4) enum { CBRET_NONE=0,CBRET_STOP=1 }; extern Bit8u lastint; + INLINE RealPt CALLBACK_RealPointer(Bitu callback) { - return RealMake(CB_SEG,callback << 4); + return RealMake(CB_SEG,callback*CB_SIZE); } INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { - return PhysMake(CB_SEG,callback << 4); + return PhysMake(CB_SEG,callback*CB_SIZE); +} + +INLINE PhysPt CALLBACK_GetBase(void) { + return CB_SEG << 4; } Bitu CALLBACK_Allocate(); @@ -54,7 +61,7 @@ void CALLBACK_Idle(void); void CALLBACK_RunRealInt(Bit8u intnum); void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); -bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* description=0); +bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr); Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr); const char* CALLBACK_GetDescription(Bitu callback); @@ -85,7 +92,7 @@ public: //Only allocate a callback number void Allocate(CallBack_Handler handler,const char* description=0); Bit16u Get_callback(){return m_callback;} - RealPt Get_RealPointer(){ return RealMake(CB_SEG,m_callback << 4);} + RealPt Get_RealPointer(){ return CALLBACK_RealPointer(m_callback);} void Set_RealVec(Bit8u vec); }; #endif diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 45a56f32..fe4cfde4 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.33 2006-06-25 18:49:32 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.34 2006-07-24 19:06:55 c2woody Exp $ */ #include #include @@ -26,7 +26,7 @@ #include "mem.h" #include "cpu.h" -/* CallBack are located at 0xC800:0 +/* CallBack are located at 0xF100:0 (see CB_SEG in callback.h) And they are 16 bytes each and you can define them to behave in certain ways like a far return or and IRET */ @@ -65,7 +65,7 @@ void CALLBACK_Idle(void) { Bit16u oldcs=SegValue(cs); Bit32u oldeip=reg_eip; SegSet16(cs,CB_SEG); - reg_eip=call_idle<<4; + reg_eip=call_idle*CB_SIZE; DOSBOX_RunMachine(); reg_eip=oldeip; SegSet16(cs,oldcs); @@ -87,7 +87,7 @@ static Bitu stop_handler(void) { void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { reg_sp-=4; - mem_writew(SegPhys(ss)+reg_sp,call_stop<<4); + mem_writew(SegPhys(ss)+reg_sp,call_stop*CB_SIZE); mem_writew(SegPhys(ss)+reg_sp+2,CB_SEG); Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); @@ -101,7 +101,7 @@ void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) { void CALLBACK_RunRealInt(Bit8u intnum) { Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); - reg_eip=(CB_MAX*16)+(intnum*6); + reg_eip=(CB_MAX*CB_SIZE)+(intnum*6); SegSet16(cs,CB_SEG); DOSBOX_RunMachine(); reg_eip=oldeip; @@ -133,65 +133,254 @@ const char* CALLBACK_GetDescription(Bitu nr) { return CallBack_Description[nr]; }; -Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { +Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_cb=true) { if (callback>=CB_MAX) return 0; switch (type) { case CB_RETN: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2, callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0xC3); //A RETN Instruction - return 5; + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02, callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0xC3); //A RETN Instruction + return (use_cb?5:1); case CB_RETF: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2, callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0xCB); //A RETF Instruction - return 5; + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02, callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0xCB); //A RETF Instruction + return (use_cb?5:1); case CB_IRET: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2,callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0xCF); //An IRET Instruction - return 5; + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction + return (use_cb?5:1); case CB_IRETD: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2,callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0x66); //An IRETD Instruction - phys_writeb(physAddress+5,(Bit8u)0xCF); - return 6; + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0x66); //An IRETD Instruction + phys_writeb(physAddress+0x01,(Bit8u)0xCF); + return (use_cb?6:2); case CB_IRET_STI: - phys_writeb(physAddress+0,(Bit8u)0xFB); //STI - phys_writeb(physAddress+1,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+2,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+3, callback); //The immediate word - phys_writeb(physAddress+5,(Bit8u)0xCF); //An IRET Instruction - return 6; + phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI + if (use_cb) { + phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x03, callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction + return (use_cb?6:2); case CB_IRET_EOI_PIC1: - phys_writeb(physAddress+0,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+1,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+2,callback); //The immediate word - phys_writeb(physAddress+4,(Bit8u)0x50); // push ax - phys_writeb(physAddress+5,(Bit8u)0xb0); // mov al, 0x20 - phys_writeb(physAddress+6,(Bit8u)0x20); - phys_writeb(physAddress+7,(Bit8u)0xe6); // out 0x20, al - phys_writeb(physAddress+8,(Bit8u)0x20); - phys_writeb(physAddress+9,(Bit8u)0x58); // pop ax - phys_writeb(physAddress+10,(Bit8u)0xcf);//An IRET Instruction - return 11; + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writeb(physAddress+0x01,(Bit8u)0xb0); // mov al, 0x20 + phys_writeb(physAddress+0x02,(Bit8u)0x20); + phys_writeb(physAddress+0x03,(Bit8u)0xe6); // out 0x20, al + phys_writeb(physAddress+0x04,(Bit8u)0x20); + phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x0b:0x07); + case CB_IRQ0: // timer int8 + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writeb(physAddress+0x01,(Bit8u)0x52); // push dx + phys_writeb(physAddress+0x02,(Bit8u)0x1e); // push ds + phys_writew(physAddress+0x03,(Bit16u)0x1ccd); // int 1c + phys_writeb(physAddress+0x05,(Bit8u)0xfa); // cli + phys_writeb(physAddress+0x06,(Bit8u)0x1f); // pop ds + phys_writeb(physAddress+0x07,(Bit8u)0x5a); // pop dx + phys_writew(physAddress+0x08,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x0a,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x0c,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x0d,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x12:0x0e); + case CB_IRQ1: // keyboard int9 + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60 + phys_writew(physAddress+0x03,(Bit16u)0x4fb4); // mov ah, 0x4f + phys_writeb(physAddress+0x05,(Bit8u)0xf9); // stc + phys_writew(physAddress+0x06,(Bit16u)0x15cd); // int 15 + if (use_cb) { + phys_writew(physAddress+0x08,(Bit16u)0x0473); // jc skip + phys_writeb(physAddress+0x0a,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x0b,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x0c,callback); //The immediate word + // jump here to (skip): + physAddress+=6; + } + phys_writeb(physAddress+0x08,(Bit8u)0xfa); // cli + phys_writew(physAddress+0x09,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x0b,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x0d,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x15:0x0f); + case CB_IRQ9: // pic cascade interrupt + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writew(physAddress+0x01,(Bit16u)0x61b0); // mov al, 0x61 + phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al + phys_writew(physAddress+0x05,(Bit16u)0x0acd); // int a + phys_writeb(physAddress+0x07,(Bit8u)0xfa); // cli + phys_writeb(physAddress+0x08,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x09,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x0e:0x0a); + case CB_IRQ12: // ps2 mouse int74 + if (!use_cb) E_Exit("int74 callback must implement a callback handler!"); + phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds + phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es + phys_writew(physAddress+0x02,(Bit16u)0x6066); // pushad + phys_writeb(physAddress+0x04,(Bit8u)0xfb); // sti + phys_writeb(physAddress+0x05,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x06,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x07,callback); //The immediate word + return 0x09; + case CB_IRQ12_RET: // ps2 mouse int74 return + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli + phys_writew(physAddress+0x01,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al + phys_writew(physAddress+0x05,(Bit16u)0x20e6); // out 0x20, al + phys_writew(physAddress+0x07,(Bit16u)0x6166); // popad + phys_writeb(physAddress+0x09,(Bit8u)0x07); // pop es + phys_writeb(physAddress+0x0a,(Bit8u)0x1f); // pop ds + phys_writeb(physAddress+0x0b,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x10:0x0c); + case CB_IRQ6_PCJR: // pcjr keyboard interrupt + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60 + phys_writew(physAddress+0x03,(Bit16u)0xe03c); // cmp al, 0xe0 + if (use_cb) { + phys_writew(physAddress+0x05,(Bit16u)0x0674); // je skip + phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x09,callback); //The immediate word + physAddress+=4; + } else { + phys_writew(physAddress+0x05,(Bit16u)0x0274); // je skip + } + phys_writew(physAddress+0x07,(Bit16u)0x09cd); // int 9 + // jump here to (skip): + phys_writeb(physAddress+0x09,(Bit8u)0xfa); // cli + phys_writew(physAddress+0x0a,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x0c,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x0e,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x0f,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x14:0x10); + case CB_INT16: + phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI + if (use_cb) { + phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x03, callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction + for (Bitu i=0;i<=0x0b;i++) phys_writeb(physAddress+0x02+i,0x90); + phys_writew(physAddress+0x0e,(Bit16u)0xedeb); //jmp callback + return (use_cb?0x10:0x0c); + case CB_INT29: // fast console output + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writew(physAddress+0x01,(Bit8u)0x0eb4); // mov ah, 0x0e + phys_writew(physAddress+0x03,(Bit8u)0x10cd); // int 10 + phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x0b:0x07); case CB_HOOKABLE: - phys_writeb(physAddress+0,(Bit8u)0xEB); //jump near - phys_writeb(physAddress+1,(Bit8u)0x03); //offset - phys_writeb(physAddress+2,(Bit8u)0x90); //NOP - phys_writeb(physAddress+3,(Bit8u)0x90); //NOP - phys_writeb(physAddress+4,(Bit8u)0x90); //NOP - phys_writeb(physAddress+5,(Bit8u)0xFE); //GRP 4 - phys_writeb(physAddress+6,(Bit8u)0x38); //Extra Callback instruction - phys_writew(physAddress+7,callback); //The immediate word - phys_writeb(physAddress+9,(Bit8u)0xCB); //A RETF Instruction - return 10; + phys_writeb(physAddress+0x00,(Bit8u)0xEB); //jump near + phys_writeb(physAddress+0x01,(Bit8u)0x03); //offset + phys_writeb(physAddress+0x02,(Bit8u)0x90); //NOP + phys_writeb(physAddress+0x03,(Bit8u)0x90); //NOP + phys_writeb(physAddress+0x04,(Bit8u)0x90); //NOP + if (use_cb) { + phys_writeb(physAddress+0x05,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x06,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x07,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x05,(Bit8u)0xCB); //A RETF Instruction + return (use_cb?0x0a:0x06); + case CB_TDE_IRET: // TandyDAC end transfer + if (use_cb) { + phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x02,callback); //The immediate word + physAddress+=4; + } + phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax + phys_writeb(physAddress+0x01,(Bit8u)0xb8); // mov ax, 0x91fb + phys_writew(physAddress+0x02,(Bit16u)0x91fb); + phys_writew(physAddress+0x04,(Bit16u)0x15cd); // int 15 + phys_writeb(physAddress+0x06,(Bit8u)0xfa); // cli + phys_writew(physAddress+0x07,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x09,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x0b,(Bit8u)0x58); // pop ax + phys_writeb(physAddress+0x0c,(Bit8u)0xcf); //An IRET Instruction + return (use_cb?0x11:0x0d); +/* case CB_IPXESR: // IPX ESR + if (!use_cb) E_Exit("ipx esr must implement a callback handler!"); + phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds + phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es + phys_writew(physAddress+0x02,(Bit16u)0xa00f); // push fs + phys_writew(physAddress+0x04,(Bit16u)0xa80f); // push gs + phys_writeb(physAddress+0x06,(Bit8u)0x60); // pusha + phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4 + phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction + phys_writew(physAddress+0x09,callback); //The immediate word + phys_writeb(physAddress+0x0b,(Bit8u)0xCB); //A RETF Instruction + return 0x0c; + case CB_IPXESR_RET: // IPX ESR return + if (use_cb) E_Exit("ipx esr return must not implement a callback handler!"); + phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli + phys_writew(physAddress+0x01,(Bit16u)0x20b0); // mov al, 0x20 + phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al + phys_writew(physAddress+0x05,(Bit16u)0x20e6); // out 0x20, al + phys_writeb(physAddress+0x07,(Bit8u)0x61); // popa + phys_writew(physAddress+0x08,(Bit16u)0xA90F); // pop gs + phys_writew(physAddress+0x0a,(Bit16u)0xA10F); // pop fs + phys_writeb(physAddress+0x0c,(Bit8u)0x07); // pop es + phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds + phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction + return 0x0f; */ default: E_Exit("CALLBACK:Setup:Illegal type %d",type); } @@ -200,7 +389,7 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress) { bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr) { if (callback>=CB_MAX) return false; - CALLBACK_SetupExtra(callback,type,CB_BASE+(callback<<4)+0); + CALLBACK_SetupExtra(callback,type,CALLBACK_PhysPointer(callback)+0,(handler!=NULL)); CallBack_Handlers[callback]=handler; CALLBACK_SetDescription(callback,descr); return true; @@ -208,7 +397,7 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr) { if (callback>=CB_MAX) return 0; - Bitu csize=CALLBACK_SetupExtra(callback,type,addr); + Bitu csize=CALLBACK_SetupExtra(callback,type,addr,(handler!=NULL)); if (csize>0) { CallBack_Handlers[callback]=handler; CALLBACK_SetDescription(callback,descr); @@ -218,7 +407,7 @@ Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr void CALLBACK_RemoveSetup(Bitu callback) { for (Bitu i = 0;i < 16;i++) { - phys_writeb(CB_BASE+(callback<<4)+i ,(Bit8u) 0x00); + phys_writeb(CALLBACK_PhysPointer(callback)+i ,(Bit8u) 0x00); } } @@ -259,6 +448,7 @@ void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,PhysPt a CALLBACK_Setup(m_callback,handler,type,addr,description); } else E_Exit("Allready installed"); } + void CALLBACK_HandlerObject::Allocate(CallBack_Handler handler,const char* description) { if(!installed) { installed=true; @@ -282,21 +472,23 @@ void CALLBACK_Init(Section* sec) { for (i=0;i #include @@ -981,21 +981,19 @@ static Bitu DOS_21Handler(void) { }; - static Bitu DOS_20Handler(void) { - reg_ax=0x4c00; DOS_21Handler(); return CBRET_NONE; } -static Bitu DOS_27Handler(void) -{ +static Bitu DOS_27Handler(void) { // Terminate & stay resident Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true); return CBRET_NONE; } + static Bitu DOS_25Handler(void) { if(Drives[reg_al]==0){ reg_ax=0x8002; @@ -1020,20 +1018,6 @@ static Bitu DOS_26Handler(void) { } return CBRET_NONE; } -static Bitu DOS_28Handler(void) { - return CBRET_NONE; -} - -static Bitu DOS_29Handler(void) { - static bool int29warn=false; - if(!int29warn) { - LOG(LOG_DOSMISC,LOG_WARN)("Int 29 called. Redirecting to int 10:0x0e"); - int29warn=true; - } - reg_ah=0x0e; - CALLBACK_RunRealInt(0x10); - return CBRET_NONE; -} class DOS:public Module_base{ @@ -1056,11 +1040,17 @@ public: callback[4].Install(DOS_27Handler,CB_IRET,"DOS Int 27"); callback[4].Set_RealVec(0x27); - callback[5].Install(DOS_28Handler,CB_IRET,"DOS Int 28"); + callback[5].Install(NULL,CB_IRET,"DOS Int 28"); callback[5].Set_RealVec(0x28); - callback[6].Install(DOS_29Handler,CB_IRET,"CON Output Int 29"); + callback[6].Install(NULL,CB_INT29,"CON Output Int 29"); callback[6].Set_RealVec(0x29); + // pseudocode for CB_INT29: + // push ax + // mov ah, 0x0e + // int 0x10 + // pop ax + // iret DOS_SetupFiles(); /* Setup system File tables */ DOS_SetupDevices(); /* Setup dos devices */ diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 3efd14b2..6f6fa121 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: bios.cpp,v 1.61 2006-05-28 09:40:42 qbix79 Exp $ */ +/* $Id: bios.cpp,v 1.62 2006-07-24 19:06:55 c2woody Exp $ */ #include "dosbox.h" #include "mem.h" @@ -61,14 +61,8 @@ static Bitu INT70_Handler(void) { IO_Write(0x20,0x20); return 0; } -// Irq 9 calls irq 2 -static Bitu INT71_Handler() { - IO_Write(0xa0,0x61); - CALLBACK_RunRealInt(0xa); - return CBRET_NONE; -} -CALLBACK_HandlerObject* tandy_DAC_callback; +CALLBACK_HandlerObject* tandy_DAC_callback[2]; static struct { Bit16u port; Bit8u irq; @@ -143,9 +137,9 @@ static void Tandy_SetupTransfer(PhysPt bufpt,bool isplayback) { /* revector IRQ-handler if necessary */ RealPt current_irq=RealGetVec(tandy_sb.irq+8); - if (current_irq!=tandy_DAC_callback->Get_RealPointer()) { + if (current_irq!=tandy_DAC_callback[0]->Get_RealPointer()) { real_writed(0x40,0xd6,current_irq); - RealSetVec(tandy_sb.irq+8,tandy_DAC_callback->Get_RealPointer()); + RealSetVec(tandy_sb.irq+8,tandy_DAC_callback[0]->Get_RealPointer()); } IO_Write(tandy_sb.port+0xc,0xd0); /* stop DMA transfer */ @@ -222,12 +216,8 @@ static Bitu IRQ_TandyDAC(void) { IO_Read(tandy_sb.port+0xe); /* issue BIOS tandy sound device busy callout */ - Bit16u oldax=reg_ax; - reg_ax=0x91fb; - CALLBACK_RunRealInt(0x15); - reg_ax = oldax; - - IO_Write(0x20,0x20); + SegSet16(cs, RealSeg(tandy_DAC_callback[1]->Get_RealPointer())); + reg_ip = RealOff(tandy_DAC_callback[1]->Get_RealPointer()); } return CBRET_NONE; } @@ -338,16 +328,6 @@ static Bitu INT8_Handler(void) { if (val) mem_writeb(BIOS_DISK_MOTOR_TIMEOUT,val-1); /* and running drive */ mem_writeb(BIOS_DRIVE_RUNNING,mem_readb(BIOS_DRIVE_RUNNING) & 0xF0); - // Save ds,dx,ax - Bit16u oldds = SegValue(ds); - Bit16u olddx = reg_dx; - Bit16u oldax = reg_ax; - // run int 1c - CALLBACK_RunRealInt(0x1c); - // restore old values - SegSet16(ds,oldds); - reg_dx = olddx; - reg_ax = oldax; return CBRET_NONE; }; @@ -824,14 +804,24 @@ public: BIOS(Section* configuration):Module_base(configuration){ /* tandy DAC can be requested in tandy_sound.cpp by initializing this field */ bool use_tandyDAC=(real_readb(0x40,0xd4)==0xff); + /* Clear the Bios Data Area (0x400-0x5ff, 0x600- is accounted to DOS) */ for (Bit16u i=0;i<0x200;i++) real_writeb(0x40,i,0); + /* Setup all the interrupt handlers the bios controls */ /* INT 8 Clock IRQ Handler */ - //TODO Maybe give this a special callback that will also call int 8 instead of starting - //a new system - callback[0].Install(INT8_Handler,CB_IRET_EOI_PIC1,"Int 8 Clock"); + callback[0].Install(INT8_Handler,CB_IRQ0,"Int 8 Clock"); callback[0].Set_RealVec(0x8); + // pseudocode for CB_IRQ0: + // callback INT8_Handler + // push ax,dx,ds + // int 0x1c + // cli + // pop ds,dx + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret mem_writed(BIOS_TIMER,0); //Calculate the correct time @@ -880,15 +870,20 @@ public: callback[8].Install(&INT70_Handler,CB_IRET,"Int 70 RTC"); callback[8].Set_RealVec(0x70); - /* Irq 9 routed to irq 2 (which is an iret at f000:ff53) */ - callback[9].Install(&INT71_Handler,CB_IRET,"irq 9 bios"); + /* Irq 9 rerouted to irq 2 */ + callback[9].Install(NULL,CB_IRQ9,"irq 9 bios"); callback[9].Set_RealVec(0x71); + /* Irq 2 */ + RealPt irq2pt=RealMake(0xf000,0xff55); /* Ghost busters 2 mt32 mode */ + Bitu call_irq2=CALLBACK_Allocate(); + CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(irq2pt),"irq 2 bios"); + RealSetVec(0x0a,irq2pt); + /* Some hardcoded vectors */ phys_writeb(0xfff53,0xcf); /* bios default interrupt vector location */ phys_writeb(0xfe987,0xea); /* original IRQ1 location (Defender booter) */ phys_writed(0xfe988,RealGetVec(0x09)); - RealSetVec(0xA,0xf000ff53); /* Ghost busters 2 mt32 mode */ if (machine==MCH_TANDY) phys_writeb(0xffffe,0xff) ; /* Tandy model */ else if (machine==MCH_PCJR) phys_writeb(0xffffe,0xfd); /* PCJr model */ @@ -902,8 +897,20 @@ public: real_writeb(0x40,0xd4,0xff); /* tandy DAC init value */ real_writed(0x40,0xd6,0x00000000); /* install the DAC callback handler */ - tandy_DAC_callback=new CALLBACK_HandlerObject(); - tandy_DAC_callback->Install(&IRQ_TandyDAC,CB_IRET,"Tandy DAC IRQ"); + tandy_DAC_callback[0]=new CALLBACK_HandlerObject(); + tandy_DAC_callback[1]=new CALLBACK_HandlerObject(); + tandy_DAC_callback[0]->Install(&IRQ_TandyDAC,CB_IRET,"Tandy DAC IRQ"); + tandy_DAC_callback[1]->Install(NULL,CB_TDE_IRET,"Tandy DAC end transfer"); + // pseudocode for CB_TDE_IRET: + // push ax + // mov ax, 0x91fb + // int 15 + // cli + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret + RealPt current_irq=RealGetVec(tandy_sb.irq+8); real_writed(0x40,0xd6,current_irq); for (Bitu i=0; i<0x10; i++) phys_writeb(PhysMake(0xf000,0xa084+i),0x80); @@ -912,60 +919,59 @@ public: /* Setup some stuff in 0x40 bios segment */ /* detect parallel ports */ - Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers - Bitu ppindex=0; // number of lpt ports - if ((IO_Read(0x378)!=0xff)|(IO_Read(0x379)!=0xff)) { - // this is our LPT1 - mem_writew(BIOS_ADDRESS_LPT1,0x378); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { - // this is our LPT2 - mem_writew(BIOS_ADDRESS_LPT2,0x278); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + Bit8u DEFAULTPORTTIMEOUT = 10; // 10 whatevers + Bitu ppindex=0; // number of lpt ports + if ((IO_Read(0x378)!=0xff)|(IO_Read(0x379)!=0xff)) { + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x378); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; - if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { - // this is our LPT3 - mem_writew(BIOS_ADDRESS_LPT3,0x3bc); - mem_writeb(BIOS_LPT3_TIMEOUT,DEFAULTPORTTIMEOUT); + if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x278); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { + // this is our LPT3 + mem_writew(BIOS_ADDRESS_LPT3,0x3bc); + mem_writeb(BIOS_LPT3_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x3bc); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { - // this is our LPT2 - mem_writew(BIOS_ADDRESS_LPT2,0x3bc); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x3bc); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT2 + mem_writew(BIOS_ADDRESS_LPT2,0x278); + mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); + ppindex++; + } + } else if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { + // this is our LPT1 + mem_writew(BIOS_ADDRESS_LPT1,0x278); + mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); ppindex++; } - } else if((IO_Read(0x3bc)!=0xff)|(IO_Read(0x3be)!=0xff)) { - // this is our LPT1 - mem_writew(BIOS_ADDRESS_LPT1,0x3bc); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { - // this is our LPT2 - mem_writew(BIOS_ADDRESS_LPT2,0x278); - mem_writeb(BIOS_LPT2_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - } - } - else if((IO_Read(0x278)!=0xff)|(IO_Read(0x279)!=0xff)) { - // this is our LPT1 - mem_writew(BIOS_ADDRESS_LPT1,0x278); - mem_writeb(BIOS_LPT1_TIMEOUT,DEFAULTPORTTIMEOUT); - ppindex++; - } - /* Setup equipment list */ - // look http://www.bioscentral.com/misc/bda.htm - - //Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel - Bitu config = 0x0; - - // set number of parallel ports - // if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified - //else if(ppindex == 1) config |= 0x0000; - if(ppindex == 2) config |= 0x4000; - else config |= 0xc000; // 3 ports + /* Setup equipment list */ + // look http://www.bioscentral.com/misc/bda.htm + + //Bitu config=0x4400; //1 Floppy, 2 serial and 1 parrallel + Bitu config = 0x0; + + // set number of parallel ports + // if(ppindex == 0) config |= 0x8000; // looks like 0 ports are not specified + //else if(ppindex == 1) config |= 0x0000; + if(ppindex == 2) config |= 0x4000; + else config |= 0xc000; // 3 ports #if (C_FPU) //FPU config|=0x2; @@ -1007,15 +1013,17 @@ public: IO_Write(tandy_sb.port+0xc,0xd0); } real_writeb(0x40,0xd4,0x00); - if (tandy_DAC_callback) { + if (tandy_DAC_callback[0]) { Bit32u orig_vector=real_readd(0x40,0xd6); - if (orig_vector==tandy_DAC_callback->Get_RealPointer()) { + if (orig_vector==tandy_DAC_callback[0]->Get_RealPointer()) { /* set IRQ vector to old value */ RealSetVec(tandy_sb.irq+8,real_readd(0x40,0xd6)); real_writed(0x40,0xd6,0x00000000); } - delete tandy_DAC_callback; - tandy_DAC_callback=NULL; + delete tandy_DAC_callback[0]; + delete tandy_DAC_callback[1]; + tandy_DAC_callback[0]=NULL; + tandy_DAC_callback[1]=NULL; } } }; diff --git a/src/ints/bios_keyboard.cpp b/src/ints/bios_keyboard.cpp index 0a524e95..fae8a6e6 100644 --- a/src/ints/bios_keyboard.cpp +++ b/src/ints/bios_keyboard.cpp @@ -223,32 +223,14 @@ static bool check_key(Bit16u &code) { */ - +/* the scancode is in reg_al */ static Bitu IRQ1_Handler(void) { -/* handling of the locks key is difficult as sdl only gives states for - * numlock capslock. +/* handling of the locks key is difficult as sdl only gives + * states for numlock capslock. */ -/* in reg_al is the scancode */ - - /* Read the code */ - Bitu scancode; //,ascii,mod; -#if 1 - scancode=reg_al; //IO_Read(0x60); moved out of handler - - -#else - /* Old code capable of unicode keys. Dropped Readkey disabled in keyboard.cpp */ - KEYBOARD_ReadKey(scancode,ascii,mod); - LOG_MSG("Got code %X ascii %C mod %X",scancode,ascii,mod); -#endif - Bit16u old_ax=reg_ax; - reg_flags|=1; - reg_ah=0x4f;reg_al=scancode; - CALLBACK_RunRealInt(0x15); - reg_ax=old_ax;Bit8u flags1,flags2,flags3,leds; - if (!(reg_flags&1)) goto irq1_return; - + Bitu scancode=reg_al; /* Read the code */ + Bit8u flags1,flags2,flags3,leds; flags1=mem_readb(BIOS_KEYBOARD_FLAGS1); flags2=mem_readb(BIOS_KEYBOARD_FLAGS2); flags3=mem_readb(BIOS_KEYBOARD_FLAGS3); @@ -334,7 +316,7 @@ static Bitu IRQ1_Handler(void) { mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2|8); IO_Write(0x20,0x20); while (mem_readb(BIOS_KEYBOARD_FLAGS2)&8) CALLBACK_Idle(); // pause loop - reg_ip+=4; // skip out 20,20 + reg_ip+=5; // skip out 20,20 return CBRET_NONE; } } else { @@ -460,7 +442,6 @@ irq1_end: mem_writeb(BIOS_KEYBOARD_FLAGS2,flags2); mem_writeb(BIOS_KEYBOARD_FLAGS3,flags3); mem_writeb(BIOS_KEYBOARD_LEDS,leds); -irq1_return: /* IO_Write(0x20,0x20); moved out of handler to be virtualizable */ #if 0 /* Signal the keyboard for next code */ @@ -472,22 +453,6 @@ irq1_return: return CBRET_NONE; } -static Bitu IRQ6_Handler(void) { - Bit8u scancode=IO_Read(0x60); - /* skip extended keys, all of them should map quite nicely - onto corresponding non-extended keys */ - if (scancode!=0xe0) { - Bit16u old_ax=reg_ax; - reg_al=scancode; - /* call the real keyboard IRQ now, with the scancode in AL */ - CALLBACK_RunRealInt(0x09); - reg_ax=old_ax; - } - - IO_Write(0x20,0x20); - return CBRET_NONE; -} - /* check whether key combination is enhanced or not, translate key if necessary */ @@ -519,30 +484,25 @@ static Bitu INT16_Handler(void) { Bit16u temp=0; switch (reg_ah) { case 0x00: /* GET KEYSTROKE */ - for (;;) { - if (get_key(temp)) { - if (!IsEnhancedKey(temp)) { - /* normal key, exit scanning for keys */ - break; - } - } - CALLBACK_Idle(); + if ((get_key(temp)) && (!IsEnhancedKey(temp))) { + /* normal key found, return translated key in ax */ + reg_ax=temp; + } else { + /* enter small idle loop to allow for irqs to happen */ + reg_ip+=1; } - /* normal key found, return translated key in ax */ - reg_ax=temp; break; case 0x10: /* GET KEYSTROKE (enhanced keyboards only) */ - for (;;) { - if (get_key(temp)) { - if (((temp&0xff)==0xf0) && (temp>>8)) { - /* special enhanced key, clear low part before returning key */ - temp&=0xff00; - } - break; + if (get_key(temp)) { + if (((temp&0xff)==0xf0) && (temp>>8)) { + /* special enhanced key, clear low part before returning key */ + temp&=0xff00; } - CALLBACK_Idle(); + reg_ax=temp; + } else { + /* enter small idle loop to allow for irqs to happen */ + reg_ip+=1; } - reg_ax=temp; break; case 0x01: /* CHECK FOR KEYSTROKE */ for (;;) { @@ -561,7 +521,7 @@ static Bitu INT16_Handler(void) { CALLBACK_SZF(true); break; } - CALLBACK_Idle(); +// CALLBACK_Idle(); } break; case 0x11: /* CHECK FOR KEYSTROKE (enhanced keyboards only) */ @@ -630,37 +590,51 @@ static void InitBiosSegment(void) { mem_writeb(BIOS_KEYBOARD_FLAGS3,16); /* Enhanced keyboard installed */ mem_writeb(BIOS_KEYBOARD_TOKEN,0); mem_writeb(BIOS_KEYBOARD_LEDS,leds); - } void BIOS_SetupKeyboard(void) { /* Init the variables */ InitBiosSegment(); - /* Allocate a callback for int 0x16 and for standard IRQ 1 handler */ + + /* Allocate/setup a callback for int 0x16 and for standard IRQ 1 handler */ call_int16=CALLBACK_Allocate(); - call_irq1=CALLBACK_Allocate(); - CALLBACK_Setup(call_int16,&INT16_Handler,CB_IRET_STI,"keyboard"); + CALLBACK_Setup(call_int16,&INT16_Handler,CB_INT16,"keyboard"); RealSetVec(0x16,CALLBACK_RealPointer(call_int16)); - CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRET,"keyboard irq"); + + call_irq1=CALLBACK_Allocate(); + CALLBACK_Setup(call_irq1,&IRQ1_Handler,CB_IRQ1,"keyboard irq"); RealSetVec(0x9,CALLBACK_RealPointer(call_irq1)); + // pseudocode for CB_IRQ1: + // push ax + // in al, 0x60 + // mov ah, 0x4f + // stc + // int 15 + // jc skip + // callback IRQ1_Handler + // label skip: + // cli + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret + if (machine==MCH_PCJR) { call_irq6=CALLBACK_Allocate(); - CALLBACK_Setup(call_irq6,&IRQ6_Handler,CB_IRET,"PCJr kb irq"); + CALLBACK_Setup(call_irq6,NULL,CB_IRQ6_PCJR,"PCJr kb irq"); RealSetVec(0x0e,CALLBACK_RealPointer(call_irq6)); + // pseudocode for CB_IRQ6_PCJR: + // push ax + // in al, 0x60 + // cmp al, 0xe0 + // je skip + // int 0x09 + // label skip: + // cli + // mov al, 0x20 + // out 0x20, al + // pop ax + // iret } - - /* bring the all port operations outside the callback */ - phys_writeb(CB_BASE+(call_irq1<<4)+0x00,(Bit8u)0x50); // push ax - phys_writeb(CB_BASE+(call_irq1<<4)+0x01,(Bit8u)0xe4); // in al, 0x60 - phys_writeb(CB_BASE+(call_irq1<<4)+0x02,(Bit8u)0x60); - phys_writeb(CB_BASE+(call_irq1<<4)+0x03,(Bit8u)0xFE); //GRP 4 - phys_writeb(CB_BASE+(call_irq1<<4)+0x04,(Bit8u)0x38); //Extra Callback instruction - phys_writew(CB_BASE+(call_irq1<<4)+0x05,call_irq1); //The immediate word - phys_writeb(CB_BASE+(call_irq1<<4)+0x07,(Bit8u)0xb0); // mov al, 0x20 - phys_writeb(CB_BASE+(call_irq1<<4)+0x08,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_irq1<<4)+0x09,(Bit8u)0xe6); // out 0x20, al - phys_writeb(CB_BASE+(call_irq1<<4)+0x0a,(Bit8u)0x20); - phys_writeb(CB_BASE+(call_irq1<<4)+0x0b,(Bit8u)0x58); // pop ax - phys_writeb(CB_BASE+(call_irq1<<4)+0x0c,(Bit8u)0xcf); // iret } diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index 1493b3d6..5cb157aa 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.51 2006-04-22 15:25:45 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.52 2006-07-24 19:06:55 c2woody Exp $ */ #include #include @@ -721,8 +721,8 @@ static Bitu INT67_Handler(void) { reg_di+=0x400; // advance pointer by 0x100*4 /* Set up three descriptor table entries */ - Bit32u cbseg_low=(CB_BASE&0xffff)<<16; - Bit32u cbseg_high=(CB_BASE&0x1f0000)>>16; + Bit32u cbseg_low=(CALLBACK_GetBase()&0xffff)<<16; + Bit32u cbseg_high=(CALLBACK_GetBase()&0x1f0000)>>16; /* Descriptor 1 (code segment, callback segment) */ real_writed(SegValue(ds),reg_si+0x00,0x0000ffff|cbseg_low); real_writed(SegValue(ds),reg_si+0x04,0x00009a00|cbseg_high); @@ -1161,21 +1161,23 @@ public: int67.Install(&INT67_Handler,CB_IRET,"Int 67 ems"); Bit16u call_int67=int67.Get_callback(); - /* Register the ems device */ + /* Register the ems device */ //TODO MAYBE put it in the class. DOS_Device * newdev = new device_EMM(); DOS_AddDevice(newdev); - /* Add a little hack so it appears that there is an actual ems device installed */ + /* Add a little hack so it appears that there is an actual ems device installed */ char * emsname="EMMXXXX0"; if(!emsnameseg) emsnameseg=DOS_GetMemory(2); //We have 32 bytes MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,strlen(emsname)+1); - /* Copy the callback piece into the beginning, and set the interrupt vector to it*/ + + /* Copy the callback piece into the beginning, and set the interrupt vector to it*/ char buf[16]; - MEM_BlockRead(PhysMake(CB_SEG,call_int67<<4),buf,0xa); + MEM_BlockRead(CALLBACK_PhysPointer(call_int67),buf,0xa); MEM_BlockWrite(PhysMake(emsnameseg,0),buf,0xa); RealSetVec(0x67,RealMake(emsnameseg,0),old67_pointer); - /* Clear handle and page tables */ + + /* Clear handle and page tables */ Bitu i; for (i=0;i #include @@ -34,7 +34,7 @@ #include "bios.h" -static Bitu call_int33,call_int74; +static Bitu call_int33,call_int74,int74_ret_callback; static Bit16u ps2cbseg,ps2cbofs; static bool useps2callback,ps2callbackinit; static Bit16u call_ps2; @@ -870,35 +870,32 @@ static Bitu INT74_Handler(void) { mouse.events--; /* Check for an active Interrupt Handler that will get called */ if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { - /* Save lot's of registers */ - Bit32u oldeax,oldebx,oldecx,oldedx,oldesi,oldedi,oldebp,oldesp; - Bit16u oldds,oldes,oldss; - oldeax=reg_eax;oldebx=reg_ebx;oldecx=reg_ecx;oldedx=reg_edx; - oldesi=reg_esi;oldedi=reg_edi;oldebp=reg_ebp;oldesp=reg_esp; - oldds=SegValue(ds); oldes=SegValue(es); oldss=SegValue(ss); // Save segments reg_ax=mouse.event_queue[mouse.events].type; reg_bx=mouse.event_queue[mouse.events].buttons; reg_cx=POS_X; reg_dx=POS_Y; reg_si=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); reg_di=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); - // Hmm... this look ok, but moonbase wont work with it - /*if (mouse.event_queue[mouse.events].type==MOUSE_MOVED) { - mouse.mickey_x=0; - mouse.mickey_y=0; - }*/ - CALLBACK_RunRealFar(mouse.sub_seg,mouse.sub_ofs); - reg_eax=oldeax;reg_ebx=oldebx;reg_ecx=oldecx;reg_edx=oldedx; - reg_esi=oldesi;reg_edi=oldedi;reg_ebp=oldebp;reg_esp=oldesp; - SegSet16(ds,oldds); SegSet16(es,oldes); SegSet16(ss,oldss); // Save segments - + CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); + SegSet16(cs, mouse.sub_seg); + reg_ip = mouse.sub_ofs; + } else if (useps2callback) { + CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); + DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); + } else { + SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); } - DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y); - + } else { + SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback))); + reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback)); } - IO_Write(0xa0,0x20); - IO_Write(0x20,0x20); - /* Check for more Events if so reactivate IRQ */ + return CBRET_NONE; +} + +Bitu MOUSE_UserInt_CB_Handler(void) { if (mouse.events) { PIC_ActivateIRQ(MOUSE_IRQ); } @@ -911,18 +908,40 @@ void MOUSE_Init(Section* sec) { call_int33=CALLBACK_Allocate(); CALLBACK_Setup(call_int33,&INT33_Handler,CB_IRET,"Mouse"); // Wasteland needs low(seg(int33))!=0 and low(ofs(int33))!=0 - real_writed(0,0x33<<2,RealMake(CB_SEG+1,(call_int33<<4)-0x10)); + real_writed(0,0x33<<2,RealMake(CB_SEG+1,(call_int33*CB_SIZE)-0x10)); // Callback for ps2 irq call_int74=CALLBACK_Allocate(); - CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRET,"int 74"); + CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRQ12,"int 74"); + // pseudocode for CB_IRQ12: + // push ds + // push es + // pushad + // sti + // callback INT74_Handler + // doesn't return here, but rather to CB_IRQ12_RET + // (ps2 callback/user callback inbetween if requested) + + int74_ret_callback=CALLBACK_Allocate(); + CALLBACK_Setup(int74_ret_callback,&MOUSE_UserInt_CB_Handler,CB_IRQ12_RET,"int 74 ret"); + // pseudocode for CB_IRQ12_RET: + // callback MOUSE_UserInt_CB_Handler + // cli + // mov al, 0x20 + // out 0xa0, al + // out 0x20, al + // popad + // pop es + // pop ds + // iret + Bit8u hwvec=(MOUSE_IRQ>7)?(0x70+MOUSE_IRQ-8):(0x8+MOUSE_IRQ); RealSetVec(hwvec,CALLBACK_RealPointer(call_int74)); // Callback for ps2 user callback handling useps2callback = false; ps2callbackinit = false; call_ps2=CALLBACK_Allocate(); - CALLBACK_Setup(call_ps2,&PS2_Handler,CB_IRET,"ps2 bios callback"); + CALLBACK_Setup(call_ps2,&PS2_Handler,CB_RETF,"ps2 bios callback"); ps2_callback=CALLBACK_RealPointer(call_ps2); memset(&mouse,0,sizeof(mouse)); diff --git a/src/ints/xms.cpp b/src/ints/xms.cpp index e6b8b455..1dd25635 100644 --- a/src/ints/xms.cpp +++ b/src/ints/xms.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: xms.cpp,v 1.42 2006-05-07 20:00:05 qbix79 Exp $ */ +/* $Id: xms.cpp,v 1.43 2006-07-24 19:06:55 c2woody Exp $ */ #include #include @@ -64,6 +64,11 @@ #define XMS_OUT_OF_SPACE 0xa0 #define XMS_OUT_OF_HANDLES 0xa1 #define XMS_INVALID_HANDLE 0xa2 +#define XMS_INVALID_SOURCE_HANDLE 0xa3 +#define XMS_INVALID_SOURCE_OFFSET 0xa4 +#define XMS_INVALID_DEST_HANDLE 0xa5 +#define XMS_INVALID_DEST_OFFSET 0xa6 +#define XMS_INVALID_LENGTH 0xa7 #define XMS_BLOCK_NOT_LOCKED 0xaa #define XMS_BLOCK_LOCKED 0xab #define UMB_ONLY_SMALLER_BLOCK 0xb0 @@ -123,9 +128,7 @@ Bitu XMS_QueryFreeMemory(Bit16u& largestFree, Bit16u& totalFree) { return 0; }; -Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) -// size = kb -{ +Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) { // size = kb /* Find free handle */ Bit16u index=1; while (!xms_handles[index].free) { @@ -142,8 +145,7 @@ Bitu XMS_AllocateMemory(Bitu size, Bit16u& handle) return 0; }; -Bitu XMS_FreeMemory(Bitu handle) -{ +Bitu XMS_FreeMemory(Bitu handle) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; MEM_ReleasePages(xms_handles[handle].mem); xms_handles[handle].mem=-1; @@ -166,13 +168,13 @@ Bitu XMS_MoveMemory(PhysPt bpt) { PhysPt srcpt,destpt; if (src_handle) { if (InvalidHandle(src_handle)) { - return 0xa3; /* Src Handle invalid */ + return XMS_INVALID_SOURCE_HANDLE; } if (src.offset>=(xms_handles[src_handle].size*1024U)) { - return 0xa4; /* Src Offset invalid */ + return XMS_INVALID_SOURCE_OFFSET; } if (length>xms_handles[src_handle].size*1024U-src.offset) { - return 0xa7; /* Length invalid */ + return XMS_INVALID_LENGTH; } srcpt=(xms_handles[src_handle].mem*4096)+src.offset; } else { @@ -180,13 +182,13 @@ Bitu XMS_MoveMemory(PhysPt bpt) { } if (dest_handle) { if (InvalidHandle(dest_handle)) { - return 0xa5; /* Dest Handle invalid */ + return XMS_INVALID_DEST_HANDLE; } if (dest.offset>=(xms_handles[dest_handle].size*1024U)) { - return 0xa6; /* Dest Offset invalid */ + return XMS_INVALID_DEST_OFFSET; } if (length>xms_handles[dest_handle].size*1024U-dest.offset) { - return 0xa7; /* Length invalid */ + return XMS_INVALID_LENGTH; } destpt=(xms_handles[dest_handle].mem*4096)+dest.offset; } else { @@ -197,16 +199,14 @@ Bitu XMS_MoveMemory(PhysPt bpt) { return 0; } -Bitu XMS_LockMemory(Bitu handle, Bit32u& address) -{ +Bitu XMS_LockMemory(Bitu handle, Bit32u& address) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; if (xms_handles[handle].locked<255) xms_handles[handle].locked++; address = xms_handles[handle].mem*4096; return 0; }; -Bitu XMS_UnlockMemory(Bitu handle) -{ +Bitu XMS_UnlockMemory(Bitu handle) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; if (xms_handles[handle].locked) { xms_handles[handle].locked--; @@ -215,8 +215,7 @@ Bitu XMS_UnlockMemory(Bitu handle) return XMS_BLOCK_NOT_LOCKED; }; -Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) -{ +Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; lockCount = xms_handles[handle].locked; /* Find available blocks */ @@ -228,8 +227,7 @@ Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit return 0; }; -Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) -{ +Bitu XMS_ResizeMemory(Bitu handle, Bitu newSize) { if (InvalidHandle(handle)) return XMS_INVALID_HANDLE; // Block has to be unlocked if (xms_handles[handle].locked>0) return XMS_BLOCK_LOCKED; @@ -417,9 +415,16 @@ public: Bitu i; BIOS_ZeroExtendedSize(true); DOS_AddMultiplexHandler(multiplex_xms); + /* place hookable callback in writable memory area */ xms_callback=RealMake(DOS_GetMemory(0x1),0); callbackhandler.Install(&XMS_Handler,CB_HOOKABLE,Real2Phys(xms_callback),"XMS Handler"); + // pseudocode for CB_HOOKABLE: + // jump near skip + // nop,nop,nop + // label skip: + // callback XMS_Handler + // retf for (i=0;i