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: 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;