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:
parent
fcd1a96808
commit
6215071ebc
8 changed files with 527 additions and 328 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(),¶)) 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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue