IO Exceptions (wd)
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2094
This commit is contained in:
parent
36cc519170
commit
c99f8e8710
4 changed files with 272 additions and 21 deletions
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: callback.h,v 1.10 2004-12-28 16:13:26 qbix79 Exp $ */
|
||||
|
||||
#ifndef __CALLBACK_H
|
||||
#define __CALLBACK_H
|
||||
|
||||
|
@ -55,5 +57,8 @@ bool CALLBACK_Free(Bitu callback);
|
|||
|
||||
void CALLBACK_SCF(bool val);
|
||||
void CALLBACK_SZF(bool val);
|
||||
|
||||
extern Bitu call_priv_io;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: inout.h,v 1.6 2004-12-28 16:13:26 qbix79 Exp $ */
|
||||
|
||||
#ifndef __INOUT_H
|
||||
#define __INOUT_H
|
||||
|
||||
#define IO_MAX (64*1024+3)
|
||||
|
||||
#define IO_MB 0x1
|
||||
|
@ -35,25 +40,13 @@ void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu
|
|||
void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range=0);
|
||||
void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=0);
|
||||
|
||||
INLINE void IO_WriteB(Bitu port,Bitu val) {
|
||||
io_writehandlers[0][port](port,val,1);
|
||||
};
|
||||
INLINE void IO_WriteW(Bitu port,Bitu val) {
|
||||
io_writehandlers[1][port](port,val,2);
|
||||
};
|
||||
INLINE void IO_WriteD(Bitu port,Bitu val) {
|
||||
io_writehandlers[2][port](port,val,4);
|
||||
};
|
||||
void IO_WriteB(Bitu port,Bitu val);
|
||||
void IO_WriteW(Bitu port,Bitu val);
|
||||
void IO_WriteD(Bitu port,Bitu val);
|
||||
|
||||
INLINE Bitu IO_ReadB(Bitu port) {
|
||||
return io_readhandlers[0][port](port,1);
|
||||
}
|
||||
INLINE Bitu IO_ReadW(Bitu port) {
|
||||
return io_readhandlers[1][port](port,2);
|
||||
}
|
||||
INLINE Bitu IO_ReadD(Bitu port) {
|
||||
return io_readhandlers[2][port](port,4);
|
||||
}
|
||||
Bitu IO_ReadB(Bitu port);
|
||||
Bitu IO_ReadW(Bitu port);
|
||||
Bitu IO_ReadD(Bitu port);
|
||||
|
||||
INLINE void IO_Write(Bitu port,Bit8u val) {
|
||||
IO_WriteB(port,val);
|
||||
|
@ -62,4 +55,5 @@ INLINE Bit8u IO_Read(Bitu port){
|
|||
return IO_ReadB(port);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: callback.cpp,v 1.22 2004-08-29 11:22:37 qbix79 Exp $ */
|
||||
/* $Id: callback.cpp,v 1.23 2004-12-28 16:13:26 qbix79 Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -38,6 +38,7 @@ CallBack_Handler CallBack_Handlers[CB_MAX];
|
|||
char* CallBack_Description[CB_MAX];
|
||||
|
||||
static Bitu call_stop,call_idle,call_default;
|
||||
Bitu call_priv_io;
|
||||
|
||||
static Bitu illegal_handler(void) {
|
||||
E_Exit("Illegal CallBack Called");
|
||||
|
@ -237,6 +238,24 @@ void CALLBACK_Init(Section* sec) {
|
|||
real_writed(0,0x67*4,CALLBACK_RealPointer(call_default));
|
||||
real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff
|
||||
//real_writed(0,0xf*4,0); some games don't like it
|
||||
|
||||
call_priv_io=CALLBACK_Allocate();
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,9 +16,16 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: iohandler.cpp,v 1.15 2004-12-28 16:13:26 qbix79 Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "cpu.h"
|
||||
#include "../src/cpu/lazyflags.h"
|
||||
#include "callback.h"
|
||||
|
||||
IO_WriteHandler * io_writehandlers[3][IO_MAX];
|
||||
IO_ReadHandler * io_readhandlers[3][IO_MAX];
|
||||
|
||||
|
@ -99,10 +106,236 @@ void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range) {
|
|||
}
|
||||
|
||||
|
||||
struct IOF_Entry {
|
||||
Bitu cs;
|
||||
Bitu eip;
|
||||
};
|
||||
|
||||
#define IOF_QUEUESIZE 16
|
||||
struct {
|
||||
Bitu used;
|
||||
IOF_Entry entries[IOF_QUEUESIZE];
|
||||
} iof_queue;
|
||||
|
||||
static Bits IOFaultCore(void) {
|
||||
CPU_CycleLeft+=CPU_Cycles;
|
||||
CPU_Cycles=1;
|
||||
Bitu ret=CPU_Core_Full_Run();
|
||||
CPU_CycleLeft+=CPU_Cycles;
|
||||
if (ret<0) E_Exit("Got a dosbox close machine in IO-fault core?");
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!iof_queue.used) E_Exit("IO-faul Core without IO-faul");
|
||||
IOF_Entry * entry=&iof_queue.entries[iof_queue.used-1];
|
||||
if (entry->cs == SegValue(cs) && entry->eip==reg_eip)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bitu DEBUG_EnableDebugger();
|
||||
|
||||
void IO_WriteB(Bitu port,Bitu val) {
|
||||
if (GETFLAG(VM) && (CPU_IO_Exception(port,1))) {
|
||||
LazyFlags old_lflags;
|
||||
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
|
||||
CPU_Decoder * old_cpudecoder;
|
||||
old_cpudecoder=cpudecoder;
|
||||
cpudecoder=&IOFaultCore;
|
||||
IOF_Entry * entry=&iof_queue.entries[iof_queue.used++];
|
||||
entry->cs=SegValue(cs);
|
||||
entry->eip=reg_eip;
|
||||
CPU_Push16(SegValue(cs));
|
||||
CPU_Push16(reg_ip);
|
||||
Bit8u old_al = reg_al;
|
||||
Bit16u old_dx = reg_dx;
|
||||
reg_al = val;
|
||||
reg_dx = port;
|
||||
RealPt icb = CALLBACK_RealPointer(call_priv_io);
|
||||
SegSet16(cs,RealSeg(icb));
|
||||
reg_eip = RealOff(icb)+0x08;
|
||||
FillFlags();
|
||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
|
||||
DOSBOX_RunMachine();
|
||||
iof_queue.used--;
|
||||
|
||||
reg_al = old_al;
|
||||
reg_dx = old_dx;
|
||||
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
|
||||
cpudecoder=old_cpudecoder;
|
||||
}
|
||||
else io_writehandlers[0][port](port,val,1);
|
||||
};
|
||||
|
||||
void IO_WriteW(Bitu port,Bitu val) {
|
||||
if (GETFLAG(VM) && (CPU_IO_Exception(port,2))) {
|
||||
LazyFlags old_lflags;
|
||||
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
|
||||
CPU_Decoder * old_cpudecoder;
|
||||
old_cpudecoder=cpudecoder;
|
||||
cpudecoder=&IOFaultCore;
|
||||
IOF_Entry * entry=&iof_queue.entries[iof_queue.used++];
|
||||
entry->cs=SegValue(cs);
|
||||
entry->eip=reg_eip;
|
||||
CPU_Push16(SegValue(cs));
|
||||
CPU_Push16(reg_ip);
|
||||
Bit16u old_ax = reg_ax;
|
||||
Bit16u old_dx = reg_dx;
|
||||
reg_al = val;
|
||||
reg_dx = port;
|
||||
RealPt icb = CALLBACK_RealPointer(call_priv_io);
|
||||
SegSet16(cs,RealSeg(icb));
|
||||
reg_eip = RealOff(icb)+0x0a;
|
||||
FillFlags();
|
||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
|
||||
DOSBOX_RunMachine();
|
||||
iof_queue.used--;
|
||||
|
||||
reg_ax = old_ax;
|
||||
reg_dx = old_dx;
|
||||
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
|
||||
cpudecoder=old_cpudecoder;
|
||||
}
|
||||
else io_writehandlers[1][port](port,val,2);
|
||||
};
|
||||
|
||||
void IO_WriteD(Bitu port,Bitu val) {
|
||||
if (GETFLAG(VM) && (CPU_IO_Exception(port,4))) {
|
||||
LazyFlags old_lflags;
|
||||
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
|
||||
CPU_Decoder * old_cpudecoder;
|
||||
old_cpudecoder=cpudecoder;
|
||||
cpudecoder=&IOFaultCore;
|
||||
IOF_Entry * entry=&iof_queue.entries[iof_queue.used++];
|
||||
entry->cs=SegValue(cs);
|
||||
entry->eip=reg_eip;
|
||||
CPU_Push16(SegValue(cs));
|
||||
CPU_Push16(reg_ip);
|
||||
Bit32u old_eax = reg_eax;
|
||||
Bit16u old_dx = reg_dx;
|
||||
reg_al = val;
|
||||
reg_dx = port;
|
||||
RealPt icb = CALLBACK_RealPointer(call_priv_io);
|
||||
SegSet16(cs,RealSeg(icb));
|
||||
reg_eip = RealOff(icb)+0x0c;
|
||||
FillFlags();
|
||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
|
||||
DOSBOX_RunMachine();
|
||||
iof_queue.used--;
|
||||
|
||||
reg_eax = old_eax;
|
||||
reg_dx = old_dx;
|
||||
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
|
||||
cpudecoder=old_cpudecoder;
|
||||
}
|
||||
else io_writehandlers[2][port](port,val,4);
|
||||
};
|
||||
|
||||
Bitu IO_ReadB(Bitu port) {
|
||||
if (GETFLAG(VM) && (CPU_IO_Exception(port,1))) {
|
||||
LazyFlags old_lflags;
|
||||
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
|
||||
CPU_Decoder * old_cpudecoder;
|
||||
old_cpudecoder=cpudecoder;
|
||||
cpudecoder=&IOFaultCore;
|
||||
IOF_Entry * entry=&iof_queue.entries[iof_queue.used++];
|
||||
entry->cs=SegValue(cs);
|
||||
entry->eip=reg_eip;
|
||||
CPU_Push16(SegValue(cs));
|
||||
CPU_Push16(reg_ip);
|
||||
Bit16u old_dx = reg_dx;
|
||||
reg_dx = port;
|
||||
RealPt icb = CALLBACK_RealPointer(call_priv_io);
|
||||
SegSet16(cs,RealSeg(icb));
|
||||
reg_eip = RealOff(icb)+0x00;
|
||||
FillFlags();
|
||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
|
||||
DOSBOX_RunMachine();
|
||||
iof_queue.used--;
|
||||
|
||||
Bitu retval = reg_al;
|
||||
|
||||
reg_dx = old_dx;
|
||||
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
|
||||
cpudecoder=old_cpudecoder;
|
||||
return retval;
|
||||
}
|
||||
else return io_readhandlers[0][port](port,1);
|
||||
};
|
||||
|
||||
Bitu IO_ReadW(Bitu port) {
|
||||
if (GETFLAG(VM) && (CPU_IO_Exception(port,2))) {
|
||||
LazyFlags old_lflags;
|
||||
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
|
||||
CPU_Decoder * old_cpudecoder;
|
||||
old_cpudecoder=cpudecoder;
|
||||
cpudecoder=&IOFaultCore;
|
||||
IOF_Entry * entry=&iof_queue.entries[iof_queue.used++];
|
||||
entry->cs=SegValue(cs);
|
||||
entry->eip=reg_eip;
|
||||
CPU_Push16(SegValue(cs));
|
||||
CPU_Push16(reg_ip);
|
||||
Bit16u old_dx = reg_dx;
|
||||
reg_dx = port;
|
||||
RealPt icb = CALLBACK_RealPointer(call_priv_io);
|
||||
SegSet16(cs,RealSeg(icb));
|
||||
reg_eip = RealOff(icb)+0x02;
|
||||
FillFlags();
|
||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
|
||||
DOSBOX_RunMachine();
|
||||
iof_queue.used--;
|
||||
|
||||
Bitu retval = reg_ax;
|
||||
|
||||
reg_dx = old_dx;
|
||||
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
|
||||
cpudecoder=old_cpudecoder;
|
||||
return retval;
|
||||
}
|
||||
else return io_readhandlers[1][port](port,2);
|
||||
};
|
||||
|
||||
Bitu IO_ReadD(Bitu port) {
|
||||
if (GETFLAG(VM) && (CPU_IO_Exception(port,4))) {
|
||||
LazyFlags old_lflags;
|
||||
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
|
||||
CPU_Decoder * old_cpudecoder;
|
||||
old_cpudecoder=cpudecoder;
|
||||
cpudecoder=&IOFaultCore;
|
||||
IOF_Entry * entry=&iof_queue.entries[iof_queue.used++];
|
||||
entry->cs=SegValue(cs);
|
||||
entry->eip=reg_eip;
|
||||
CPU_Push16(SegValue(cs));
|
||||
CPU_Push16(reg_ip);
|
||||
Bit16u old_dx = reg_dx;
|
||||
reg_dx = port;
|
||||
RealPt icb = CALLBACK_RealPointer(call_priv_io);
|
||||
SegSet16(cs,RealSeg(icb));
|
||||
reg_eip = RealOff(icb)+0x04;
|
||||
FillFlags();
|
||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
|
||||
DOSBOX_RunMachine();
|
||||
iof_queue.used--;
|
||||
|
||||
Bitu retval = reg_eax;
|
||||
|
||||
reg_dx = old_dx;
|
||||
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
|
||||
cpudecoder=old_cpudecoder;
|
||||
return retval;
|
||||
}
|
||||
else return io_readhandlers[2][port](port,4);
|
||||
};
|
||||
|
||||
|
||||
void IO_Init(Section * sect) {
|
||||
iof_queue.used=0;
|
||||
IO_FreeReadHandler(0,IO_MA,IO_MAX);
|
||||
IO_FreeWriteHandler(0,IO_MA,IO_MAX);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue