add ems OS-dedicated handle functionality (fixes battle chess 4000 screen bug, thanks to ripsaw for debugging this),
fix some ems error numbers Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3241
This commit is contained in:
parent
0204b90e86
commit
4652da4af5
1 changed files with 47 additions and 16 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: ems.cpp,v 1.59 2008-10-05 14:44:52 qbix79 Exp $ */
|
||||
/* $Id: ems.cpp,v 1.60 2008-11-27 18:57:45 c2woody Exp $ */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -57,12 +57,14 @@
|
|||
#define EMM_INVALID_HANDLE 0x83
|
||||
#define EMM_FUNC_NOSUP 0x84
|
||||
#define EMM_OUT_OF_HANDLES 0x85
|
||||
#define EMM_SAVEMAP_ERROR 0x86
|
||||
#define EMM_OUT_OF_PHYS 0x87
|
||||
#define EMM_OUT_OF_LOG 0x88
|
||||
#define EMM_ZERO_PAGES 0x89
|
||||
#define EMM_LOG_OUT_RANGE 0x8a
|
||||
#define EMM_ILL_PHYS 0x8b
|
||||
#define EMM_PAGE_MAP_SAVED 0x8d
|
||||
#define EMM_NO_SAVED_PAGE_MAP 0x8e
|
||||
#define EMM_INVALID_SUB 0x8f
|
||||
#define EMM_FEAT_NOSUP 0x91
|
||||
#define EMM_MOVE_OVLAP 0x92
|
||||
|
@ -210,9 +212,11 @@ static bool INLINE ValidHandle(Bit16u handle) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle) {
|
||||
static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle,bool can_allocate_zpages) {
|
||||
/* Check for 0 page allocation */
|
||||
if (!pages) return EMM_ZERO_PAGES;
|
||||
if (!pages) {
|
||||
if (!can_allocate_zpages) return EMM_ZERO_PAGES;
|
||||
}
|
||||
/* Check for enough free pages */
|
||||
if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;}
|
||||
Bit16u handle = 1;
|
||||
|
@ -229,6 +233,21 @@ static Bit8u EMM_AllocateMemory(Bit16u pages,Bit16u & dhandle) {
|
|||
return EMM_NO_ERROR;
|
||||
}
|
||||
|
||||
static Bit8u EMM_AllocateSystemHandle(Bit16u pages) {
|
||||
/* Check for enough free pages */
|
||||
if ((MEM_FreeTotal()/ 4) < pages) { return EMM_OUT_OF_LOG;}
|
||||
Bit16u handle = 0; // emm system handle (reserved for OS usage)
|
||||
/* Release memory if already allocated */
|
||||
if (emm_handles[handle].pages != NULL_HANDLE) {
|
||||
MEM_ReleasePages(emm_handles[handle].mem);
|
||||
}
|
||||
MemHandle mem = MEM_AllocatePages(pages*4,false);
|
||||
if (!mem) E_Exit("EMS:System handle memory allocation failure");
|
||||
emm_handles[handle].pages = pages;
|
||||
emm_handles[handle].mem = mem;
|
||||
return EMM_NO_ERROR;
|
||||
}
|
||||
|
||||
static Bit8u EMM_ReallocatePages(Bit16u handle,Bit16u & pages) {
|
||||
/* Check for valid handle */
|
||||
if (!ValidHandle(handle)) return EMM_INVALID_HANDLE;
|
||||
|
@ -328,10 +347,16 @@ static Bit8u EMM_MapSegment(Bitu segment,Bit16u handle,Bit16u log_page) {
|
|||
static Bit8u EMM_ReleaseMemory(Bit16u handle) {
|
||||
/* Check for valid handle */
|
||||
if (!ValidHandle(handle)) return EMM_INVALID_HANDLE;
|
||||
// should check for saved_page_map flag here, returning an error if it's true
|
||||
// as apps are required to restore the pagemap beforehand; to be checked
|
||||
MEM_ReleasePages(emm_handles[handle].mem);
|
||||
/* Reset handle */
|
||||
emm_handles[handle].mem=0;
|
||||
emm_handles[handle].pages=NULL_HANDLE;
|
||||
if (handle==0) {
|
||||
emm_handles[handle].pages=0; // OS handle is NEVER deallocated
|
||||
} else {
|
||||
emm_handles[handle].pages=NULL_HANDLE;
|
||||
}
|
||||
emm_handles[handle].saved_page_map=false;
|
||||
memset(&emm_handles[handle].name,0,8);
|
||||
return EMM_NO_ERROR;
|
||||
|
@ -372,7 +397,7 @@ static Bit8u EMM_RestorePageMap(Bit16u handle) {
|
|||
if (handle!=0) return EMM_INVALID_HANDLE;
|
||||
}
|
||||
/* Check for previous save */
|
||||
if (!emm_handles[handle].saved_page_map) return EMM_INVALID_HANDLE;
|
||||
if (!emm_handles[handle].saved_page_map) return EMM_NO_SAVED_PAGE_MAP;
|
||||
/* Restore the mappings */
|
||||
emm_handles[handle].saved_page_map=false;
|
||||
for (Bitu i=0;i<EMM_MAX_PHYS;i++) {
|
||||
|
@ -474,11 +499,11 @@ static Bit8u HandleNameSearch(void) {
|
|||
return EMM_NOT_FOUND;
|
||||
break;
|
||||
case 0x02: /* Get Total number of handles */
|
||||
reg_bx=EMM_MAX_HANDLES;
|
||||
break;
|
||||
reg_bx=EMM_MAX_HANDLES;
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al);
|
||||
return EMM_FUNC_NOSUP;
|
||||
return EMM_INVALID_SUB;
|
||||
}
|
||||
return EMM_NO_ERROR;
|
||||
}
|
||||
|
@ -496,7 +521,7 @@ static Bit8u GetSetHandleName(void) {
|
|||
break;
|
||||
default:
|
||||
LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al);
|
||||
return EMM_FUNC_NOSUP;
|
||||
return EMM_INVALID_SUB;
|
||||
}
|
||||
return EMM_NO_ERROR;
|
||||
|
||||
|
@ -630,7 +655,7 @@ static Bitu INT67_Handler(void) {
|
|||
reg_ah=EMM_NO_ERROR;
|
||||
break;
|
||||
case 0x43: /* Get Handle and Allocate Pages */
|
||||
reg_ah=EMM_AllocateMemory(reg_bx,reg_dx);
|
||||
reg_ah=EMM_AllocateMemory(reg_bx,reg_dx,false);
|
||||
break;
|
||||
case 0x44: /* Map Expanded Memory Page */
|
||||
reg_ah=EMM_MapPage(reg_al,reg_dx,reg_bx);
|
||||
|
@ -682,7 +707,7 @@ static Bitu INT67_Handler(void) {
|
|||
break;
|
||||
default:
|
||||
LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al);
|
||||
reg_ah=EMM_FUNC_NOSUP;
|
||||
reg_ah=EMM_INVALID_SUB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -710,6 +735,10 @@ static Bitu INT67_Handler(void) {
|
|||
};
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_MISC,LOG_ERROR)("EMS:Call %2X Subfunction %2X not supported",reg_ah,reg_al);
|
||||
reg_ah=EMM_INVALID_SUB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x51: /* Reallocate Pages */
|
||||
|
@ -739,11 +768,11 @@ static Bitu INT67_Handler(void) {
|
|||
reg_ah = EMM_NO_ERROR;
|
||||
break;
|
||||
case 0x5A: /* Allocate standard/raw Pages */
|
||||
if (reg_al==0x00) {
|
||||
reg_ah=EMM_AllocateMemory(reg_bx,reg_dx);
|
||||
if (reg_al<=0x01) {
|
||||
reg_ah=EMM_AllocateMemory(reg_bx,reg_dx,true); // can allocate 0 pages
|
||||
} else {
|
||||
LOG(LOG_MISC,LOG_ERROR)("EMS:Call 5A subfct %2X not supported",reg_al);
|
||||
reg_ah=EMM_FUNC_NOSUP;
|
||||
reg_ah=EMM_INVALID_SUB;
|
||||
};
|
||||
break;
|
||||
case 0xDE: /* VCPI Functions */
|
||||
|
@ -1130,7 +1159,7 @@ static void SetupVCPI() {
|
|||
vcpi.pic2_remapping=0x70; // slave PIC base
|
||||
|
||||
/* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */
|
||||
EMM_AllocateMemory(1,vcpi.ems_handle);
|
||||
EMM_AllocateMemory(1,vcpi.ems_handle,false);
|
||||
vcpi.private_area=emm_handles[vcpi.ems_handle].mem<<12;
|
||||
|
||||
/* GDT */
|
||||
|
@ -1212,7 +1241,7 @@ private:
|
|||
public:
|
||||
EMS(Section* configuration):Module_base(configuration){
|
||||
|
||||
/* Virtual DMA interrupt callback */
|
||||
/* Virtual DMA interrupt callback */
|
||||
call_vdma.Install(&INT4B_Handler,CB_IRET,"Int 4b vdma");
|
||||
call_vdma.Set_RealVec(0x4b);
|
||||
|
||||
|
@ -1261,6 +1290,8 @@ public:
|
|||
emm_segmentmappings[i].handle=NULL_HANDLE;
|
||||
}
|
||||
|
||||
EMM_AllocateSystemHandle(4); // allocate OS-dedicated handle (ems handle zero)
|
||||
|
||||
if (!ENABLE_VCPI) return;
|
||||
|
||||
/* Install a callback that handles VCPI-requests in protected mode requests */
|
||||
|
|
Loading…
Add table
Reference in a new issue