1
0
Fork 0

change callback code; get rid of several calls to DOSBOX_RunMachine()

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2677
This commit is contained in:
Sebastian Strohhäcker 2006-07-24 19:06:55 +00:00
parent fcd1a96808
commit 6215071ebc
8 changed files with 527 additions and 328 deletions

View file

@ -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

View file

@ -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 <stdlib.h>
#include <string.h>
@ -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<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(CB_BASE+(call_stop<<4)+0,0xFE);
phys_writeb(CB_BASE+(call_stop<<4)+1,0x38);
phys_writew(CB_BASE+(call_stop<<4)+2,call_stop);
phys_writeb(CALLBACK_PhysPointer(call_stop)+0,0xFE);
phys_writeb(CALLBACK_PhysPointer(call_stop)+1,0x38);
phys_writew(CALLBACK_PhysPointer(call_stop)+2,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(CB_BASE+(call_idle<<4)+i,0x90);
phys_writeb(CB_BASE+(call_idle<<4)+12,0xFE);
phys_writeb(CB_BASE+(call_idle<<4)+13,0x38);
phys_writew(CB_BASE+(call_idle<<4)+14,call_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,call_idle);
/* Setup all Interrupt to point to the default handler */
call_default=CALLBACK_Allocate();
@ -307,7 +499,7 @@ void CALLBACK_Init(Section* sec) {
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
}
/* Setup block of 0xCD 0xxx instructions */
PhysPt rint_base=CB_BASE+CB_MAX*16;
PhysPt rint_base=(CB_SEG << 4)+CB_MAX*CB_SIZE;
for (i=0;i<=0xff;i++) {
phys_writeb(rint_base,0xCD);
phys_writeb(rint_base+1,i);
@ -318,6 +510,7 @@ void CALLBACK_Init(Section* sec) {
}
// setup a few interrupt handlers that point to bios IRETs by default
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
@ -325,19 +518,20 @@ void CALLBACK_Init(Section* sec) {
call_priv_io=CALLBACK_Allocate();
phys_writeb(CB_BASE+(call_priv_io<<4)+0x00,(Bit8u)0xec); // in al, dx
phys_writeb(CB_BASE+(call_priv_io<<4)+0x01,(Bit8u)0xcb); // retf
phys_writeb(CB_BASE+(call_priv_io<<4)+0x02,(Bit8u)0xed); // in ax, dx
phys_writeb(CB_BASE+(call_priv_io<<4)+0x03,(Bit8u)0xcb); // retf
phys_writeb(CB_BASE+(call_priv_io<<4)+0x04,(Bit8u)0x66); // in eax, dx
phys_writeb(CB_BASE+(call_priv_io<<4)+0x05,(Bit8u)0xed);
phys_writeb(CB_BASE+(call_priv_io<<4)+0x06,(Bit8u)0xcb); // retf
// 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(CB_BASE+(call_priv_io<<4)+0x08,(Bit8u)0xee); // out dx, al
phys_writeb(CB_BASE+(call_priv_io<<4)+0x09,(Bit8u)0xcb); // retf
phys_writeb(CB_BASE+(call_priv_io<<4)+0x0a,(Bit8u)0xef); // out dx, ax
phys_writeb(CB_BASE+(call_priv_io<<4)+0x0b,(Bit8u)0xcb); // retf
phys_writeb(CB_BASE+(call_priv_io<<4)+0x0c,(Bit8u)0x66); // out dx, eax
phys_writeb(CB_BASE+(call_priv_io<<4)+0x0d,(Bit8u)0xef);
phys_writeb(CB_BASE+(call_priv_io<<4)+0x0e,(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
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos.cpp,v 1.94 2006-04-21 08:23:40 qbix79 Exp $ */
/* $Id: dos.cpp,v 1.95 2006-07-24 19:06:55 c2woody Exp $ */
#include <stdlib.h>
#include <string.h>
@ -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(),&para)) 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 */

View file

@ -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;
}
}
};

View file

@ -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
}

View file

@ -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 <string.h>
#include <stdlib.h>
@ -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<EMM_MAX_HANDLES;i++) {
emm_handles[i].mem=0;

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: mouse.cpp,v 1.62 2006-04-22 15:25:45 c2woody Exp $ */
/* $Id: mouse.cpp,v 1.63 2006-07-24 19:06:55 c2woody Exp $ */
#include <string.h>
#include <math.h>
@ -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));

View file

@ -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 <stdlib.h>
#include <string.h>
@ -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<XMS_HANDLES;i++) {
xms_handles[i].free=true;