1
0
Fork 0

IO Exceptions (wd)

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2094
This commit is contained in:
Peter Veenstra 2004-12-28 16:13:26 +00:00
parent 36cc519170
commit c99f8e8710
4 changed files with 272 additions and 21 deletions

View file

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

View file

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

View file

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

View file

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