#include #include #include #define _EMM_ #include "emm.h" #undef _EMM_ int isemm() { union REGS reg; struct SREGS sreg; char far *fptr; int fh,ret; ret = 0; /* open device "EMMXXXX0" */ fptr = "EMMXXXX0"; /* emm device name */ sreg.ds = FP_SEG(fptr); reg.x.dx = FP_OFF(fptr); reg.x.ax = 0x3d00; /* open handle */ intdosx(®,®,&sreg); if(reg.x.cflag) { emm.status = EMMNORDY; emm.errorno = EMMDEVER; return(0); } fh = reg.x.ax; /* file handle */ /* check device */ reg.x.bx = fh; reg.x.ax = 0x4400; /* get IOCTL */ intdos(®,®); if(!reg.x.cflag && (reg.x.dx & 0x0080)) /* is handle device */ { /* check device ready */ reg.x.bx = fh; reg.x.ax = 0x4407; /* get output IOCTL status */ intdosx(®,®,&sreg); if(!reg.x.cflag && (reg.h.al == 0xff)) /* is device ready */ ret = 1; } /* close device */ reg.x.bx = fh; reg.x.ax = 0x3e00; intdos(®,®); if(ret == 0) { emm.status = EMMNORDY; emm.errorno = EMMDEVER; return(0); } /* check ems status */ reg.h.ah = 0x40; emscall(); emm.errorno = (unsigned int)(reg.h.ah); if(emm.errorno != 0) { emm.status = EMMNORDY; return(0); } emm.status |= EMMREADY; return(1); } unsigned int emsver() { union REGS reg; if(!(emm.status & EMMREADY)) { if(!isemm()) return(0); } reg.h.ah = 0x46; emscall(); if(reg.h.ah != 0) { emm.errorno = reg.h.ah; return(0); } return((unsigned int)(reg.h.al)); } unsigned int emsphys() { union REGS reg; struct SREGS sreg; unsigned int p,f; EMMPHYS far *physical; if(emm.status & EMMGETPH) return(1); /* check version 4.0 */ if(0x40 != emsver()) { emm.errorno = EMMVERER; return(0); } /* get physical page number */ reg.x.ax = 0x5801; emscall(); if(reg.h.ah) { emm.errorno = reg.h.ah; return(0); } emm.ppages = (unsigned int)reg.x.cx; /* get physical page table */ if(NULL == (emm.ppflame = (EMMPAGES *)calloc(emm.ppages,sizeof(EMMPAGES)))) { emm.errorno = EMMMEMER; return(0); } /* get physical address table */ if(NULL == (physical = (EMMPHYS far *)_fmalloc(sizeof(EMMPHYS) * emm.ppages))) { emm.errorno = EMMMEMER; free((char *)emm.ppflame); return(0); } /* get physical page address */ reg.x.ax = 0x5800; reg.x.di = FP_OFF(physical); sreg.es = FP_SEG(physical); emscallx(); if(0 != reg.h.ah) { emm.errorno = reg.h.ah; _ffree((char far *)physical); free((char *)emm.ppflame); return(0); } /* set physical page table */ f = 0; for(p = 0;p < emm.ppages;p++) { if(physical[p].segment >= 0xa000) { emm.ppflame[f].ppage = physical[p].ppage; emm.ppflame[f].segment = physical[p].segment; emm.ppflame[f].lpage = 0xffff; f++; } } emm.epages = f; for(p = 0;p < emm.ppages;p++) { if(physical[p].segment < 0xa000) { emm.ppflame[f].ppage = physical[p].ppage; emm.ppflame[f].segment = physical[p].segment; emm.ppflame[f].lpage = 0xffff; f++; } } /* free working memory */ _ffree((char far *)physical); emm.status |= EMMGETPH; return(1); } unsigned int emsalloc(unsigned int logipage) { union REGS reg; if(emm.status & EMMALLOC) return(0); /* check version 4.0 */ if(0x40 != emsver()) { emm.errorno = EMMVERER; return(0); } /* allacation ems logical page */ reg.x.ax = 0x5a00; reg.x.bx = logipage; emscall(); if(0 != reg.h.ah) { emm.errorno = reg.h.ah; return(0); } emm.handle = reg.x.dx; emm.lpages = logipage; emm.status |= EMMALLOC; return(1); } unsigned int emsrealc(unsigned int logipage) { union REGS reg; if(!(emm.status & EMMALLOC)) return(emsalloc(logipage)); /* reallacation ems logical page */ reg.h.ah = 0x51; reg.x.dx = emm.handle; reg.x.bx = logipage; emscall(); emm.lpages = reg.x.bx; if(0 != reg.h.ah) { emm.errorno = reg.h.ah; return(0); } return(1); } unsigned int emsmap(unsigned int logipage,unsigned int physpage) { union REGS reg; unsigned int p; if(!(emm.status & EMMALLOC)) { emm.errorno = EMMALCER; return(0); } for(p = 0;p < emm.ppages;p++) { if(emm.ppflame[p].ppage == physpage) break; } if(p == emm.ppages) { emm.errorno = EMMARGER; return(0); } if(emm.ppflame[p].lpage == logipage) return(1); /* mapping ems logical page */ reg.h.ah = 0x44; reg.h.al = (unsigned char)physpage; reg.x.bx = logipage; reg.x.dx = emm.handle; emscall(); if(0 != reg.h.ah) { emm.errorno = reg.h.ah; return(0); } emm.ppflame[p].lpage = logipage; return(1); } unsigned int emsmapf(unsigned int logipage,unsigned int flame) { union REGS reg; if(!(emm.status & EMMALLOC)) { emm.errorno = EMMALCER; return(0); } if(flame >= emm.ppages) { emm.errorno = EMMARGER; return(0); } if(emm.ppflame[flame].lpage == logipage) return(1); /* mapping ems logical page */ reg.h.ah = 0x44; reg.h.al = (unsigned char)emm.ppflame[flame].ppage; reg.x.bx = logipage; reg.x.dx = emm.handle; emscall(); if(0 != reg.h.ah) { emm.errorno = reg.h.ah; return(0); } emm.ppflame[flame].lpage = logipage; return(1); } unsigned int emsfree() { union REGS reg; if(emm.status & EMMALLOC) { /* free ems logical page */ reg.h.ah = 0x45; reg.x.dx = emm.handle; emscall(); if(0 != reg.h.ah) { emm.errorno = reg.h.ah; return(0); } emm.handle = 0; emm.lpages = 0; emm.status &= ~EMMALLOC; } if(emm.status & EMMGETPH) { free((char *)emm.ppflame); emm.ppages = 0; emm.epages = 0; emm.lpages = 0; emm.ppflame = NULL; emm.status &= ~EMMGETPH; } return(1); }