From 0b6195208d82d3501c35e3236fc214f3f01896bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sun, 16 Apr 2006 20:11:04 +0000 Subject: [PATCH] implement ioctl control channels for ems device (GEMMIS support) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2601 --- src/ints/ems.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/src/ints/ems.cpp b/src/ints/ems.cpp index f19e79cb..6fe6f932 100644 --- a/src/ints/ems.cpp +++ b/src/ints/ems.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: ems.cpp,v 1.48 2006-04-07 16:34:07 c2woody Exp $ */ +/* $Id: ems.cpp,v 1.49 2006-04-16 20:11:04 c2woody Exp $ */ #include #include @@ -41,6 +41,7 @@ #define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */ #define EMM_VERSION 0x40 +#define GEMMIS_VERSION 0x0001 // Version 1.0 #define NULL_HANDLE 0xffff #define NULL_PAGE 0xffff @@ -68,10 +69,14 @@ #define EMM_MOVE_OVLAPI 0x97 #define EMM_NOT_FOUND 0xa0 +static Bit16u GEMMIS_seg; class device_EMM : public DOS_Device { public: - device_EMM(){SetName("EMMXXXX0");} + device_EMM() { + SetName("EMMXXXX0"); + GEMMIS_seg=0; + } bool Read(Bit8u * data,Bit16u * size) { return false;} bool Write(Bit8u * data,Bit16u * size){ LOG(LOG_IOCTL,LOG_NORMAL)("EMS:Write to device"); @@ -80,12 +85,82 @@ public: bool Seek(Bit32u * pos,Bit32u type){return false;} bool Close(){return false;} Bit16u GetInformation(void){return 0xc080;} - bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} + bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode){return true;} private: Bit8u cache; }; +bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode) { + Bitu subfct=mem_readb(bufptr); + switch (subfct) { + case 0x00: + if (size!=6) return false; + mem_writew(bufptr+0x00,0x0023); // ID + mem_writed(bufptr+0x02,0); // private API entry point + *retcode=6; + return true; + case 0x01: { + if (size!=6) return false; + if (GEMMIS_seg==0) GEMMIS_seg=DOS_GetMemory(0x20); + PhysPt GEMMIS_addr=PhysMake(GEMMIS_seg,0); + + mem_writew(GEMMIS_addr+0x00,0x0004); // flags + mem_writew(GEMMIS_addr+0x02,0x019d); // size of this structure + mem_writew(GEMMIS_addr+0x04,GEMMIS_VERSION); // version 1.0 (provide ems information only) + mem_writed(GEMMIS_addr+0x06,0); // reserved + + /* build non-EMS frames (0-0xe000) */ + for (Bitu frct=0; frct>4); // version 4.0 + mem_writew(bufptr+0x01,EMM_VERSION&0x0f); + *retcode=2; + return true; + } + return false; +} + struct EMM_Mapping { Bit16u handle; Bit16u page; @@ -863,7 +938,7 @@ static Bitu V86_Monitor() { if ((rm_val<0xc0) || (rm_val>=0xe8)) E_Exit("Invalid opcode 0x0f 0x20 %x caused a protection fault!",rm_val); Bit32u crx=CPU_GET_CRX(which); - switch (rm_val&3) { + switch (rm_val&7) { case 0: reg_eax=crx; break; case 1: reg_ecx=crx; break; case 2: reg_edx=crx; break; @@ -882,7 +957,7 @@ static Bitu V86_Monitor() { if ((rm_val<0xc0) || (rm_val>=0xe8)) E_Exit("Invalid opcode 0x0f 0x22 %x caused a protection fault!",rm_val); Bit32u crx; - switch (rm_val&3) { + switch (rm_val&7) { case 0: crx=reg_eax; break; case 1: crx=reg_ecx; break; case 2: crx=reg_edx; break; @@ -1069,6 +1144,7 @@ public: call_vdma.Set_RealVec(0x4b); vcpi.enabled=false; + GEMMIS_seg=0; Section_prop * section=static_cast(configuration); if (!section->Get_bool("ems")) return; @@ -1161,6 +1237,7 @@ public: /* Remove ems device */ device_EMM newdev; DOS_DelDevice(&newdev); + GEMMIS_seg=0; /* Remove the emsname and callback hack */ char buf[32]= { 0 };