diff --git a/include/callback.h b/include/callback.h index ca919ab6..291233b3 100644 --- a/include/callback.h +++ b/include/callback.h @@ -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 diff --git a/include/inout.h b/include/inout.h index bb83949b..54aaf6b8 100644 --- a/include/inout.h +++ b/include/inout.h @@ -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 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 87aaa4ac..5277031d 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.cpp,v 1.22 2004-08-29 11:22:37 qbix79 Exp $ */ +/* $Id: callback.cpp,v 1.23 2004-12-28 16:13:26 qbix79 Exp $ */ #include #include @@ -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 } diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 904af71f..85874967 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -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 +#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); } - -