From f47d48ba0715014b15d342a0dee85a36f10b4d76 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Wed, 14 Jan 2009 22:16:00 +0000 Subject: [PATCH] Start stuff with an REFT instead of IRET. Fixes CyberRace.(Beta 2) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3260 --- include/callback.h | 5 +++-- src/cpu/callback.cpp | 14 +++++++++++++- src/dos/dos.cpp | 11 ++++++++--- src/dos/dos_execute.cpp | 15 +++++++++------ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/include/callback.h b/include/callback.h index 1bfc3526..faaa8bc0 100644 --- a/include/callback.h +++ b/include/callback.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: callback.h,v 1.21 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: callback.h,v 1.22 2009-01-14 22:16:00 qbix79 Exp $ */ #ifndef DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H @@ -30,7 +30,8 @@ extern CallBack_Handler CallBack_Handlers[]; enum { CB_RETN,CB_RETF,CB_RETF8,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_MOUSE, - CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET }; + CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET, + CB_INT21 }; #define CB_MAX 128 #define CB_SIZE 32 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index ea1e167f..2f1b7f9c 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.37 2007-06-03 16:46:33 c2woody Exp $ */ +/* $Id: callback.cpp,v 1.38 2009-01-14 22:16:00 qbix79 Exp $ */ #include #include @@ -403,6 +403,18 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction return 0x0f; */ + case CB_INT21: + 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 + phys_writeb(physAddress+0x02,(Bit8u)0xCB); //A RETF Instruction + return (use_cb?7:3); + default: E_Exit("CALLBACK:Setup:Illegal type %d",type); } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 01c7d90c..e9ae9c3b 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.114 2008-12-11 09:16:31 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.115 2009-01-14 22:16:00 qbix79 Exp $ */ #include #include @@ -1041,7 +1041,7 @@ static Bitu DOS_21Handler(void) { break; }; return CBRET_NONE; -}; +} static Bitu DOS_20Handler(void) { @@ -1091,8 +1091,13 @@ public: callback[0].Install(DOS_20Handler,CB_IRET,"DOS Int 20"); callback[0].Set_RealVec(0x20); - callback[1].Install(DOS_21Handler,CB_IRET_STI,"DOS Int 21"); + callback[1].Install(DOS_21Handler,CB_INT21,"DOS Int 21"); callback[1].Set_RealVec(0x21); + //Pseudo code for int 21 + // sti + // callback + // iret + // retf <- int 21 4c jumps here to mimic a retf Cyber callback[2].Install(DOS_25Handler,CB_RETF,"DOS Int 25"); callback[2].Set_RealVec(0x25); diff --git a/src/dos/dos_execute.cpp b/src/dos/dos_execute.cpp index 021aceec..a6058a83 100644 --- a/src/dos/dos_execute.cpp +++ b/src/dos/dos_execute.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_execute.cpp,v 1.65 2008-10-05 14:44:52 qbix79 Exp $ */ +/* $Id: dos_execute.cpp,v 1.66 2009-01-14 22:16:00 qbix79 Exp $ */ #include #include @@ -457,13 +457,16 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Set the stack for new program */ SegSet16(ss,RealSeg(sssp));reg_sp=RealOff(sssp); /* Add some flags and CS:IP on the stack for the IRET */ - reg_sp-=6; + reg_sp-=4; mem_writew(SegPhys(ss)+reg_sp+0,RealOff(csip)); mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip)); - /* DOS starts programs with a RETF, so our IRET - should not modify critical flags (IOPL in v86 mode); - interrupt flag is set explicitly, test flags cleared */ - mem_writew(SegPhys(ss)+reg_sp+4,(reg_flags&(~FMASK_TEST))|FLAG_IF); + /* Old info, we now jump to a RETF: + * DOS starts programs with a RETF, so our IRET + * should not modify critical flags (IOPL in v86 mode); + * interrupt flag is set explicitly, test flags cleared */ + reg_flags=(reg_flags&(~FMASK_TEST))|FLAG_IF; + //Jump to retf so that we only need to store cs:ip on the stack + reg_ip++; /* Setup the rest of the registers */ reg_ax=reg_bx=0;reg_cx=0xff; reg_dx=pspseg;