home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
sysutl
/
veum.arc
/
TEST67H.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-01-26
|
6KB
|
279 lines
/*
NOTICE:
This code is placed in the public domain for documentation
purposes only. It helps demonstrate the Virtual Expanded
Memory Manager (VEMM) system distributed with.
(it also happens to work on a REAL EMM, such as AST's RAMpage!)
*/
/*
TEST67H Copyright (C) 1987, by Marty Ross
This test program assumes that at interrupt 67h there is
only an EMM-type supervisor installed.
Compiled under Lattice C 2.15 (NON-ANSI, sorry)
and linked with VEC.OBJ and
LIM.OBJ (provided).
*/
#include <dos.h>
#define HANDLES 4 /* Should become parameter */
#define toupper(c) (((c>='a')&&(c<='z'))?(c&223):c)
union REGS regs ;
struct SREGS sregs ;
static unsigned emm_pfba ; /* Segment address of EMM PFBA */
unsigned usedp, freep, totalp ;
unsigned vdevt ; /* "Virtual EMM DEVice Type" */
unsigned thandle[HANDLES] ; /* "test handles" */
unsigned tusedp[HANDLES] ; /* sizes of areas held by "" */
main()
{
unsigned i ;
/* Phase 1: setup */
chkout() ;
getver() ;
getstatus() ;
getpfba() ;
getsize() ;
/* Phase 2: allocation */
for (i=0;i<HANDLES;i++) {
aloc(i) ;
prt_map() ;
}
getsize() ;
for (i=0;i<HANDLES;i++) {
de_aloc(i) ;
prt_map() ;
}
getsize() ;
getstatus() ;
more() ;
/* Phase 3: data access */
printf("Example (but FAR from typical) application:\n");
aloc(0); /* alocate to my slot#0 */
use_emm(0, tusedp[0] / 2) ; /* Do some I/O with it */
de_aloc(0) ; /* Release it */
printf("Done with EMM test.\n");
}
/*
chkout:
make sure that there is at least a resemblance to an EMM
supervisor installed.
If it is a true blue EMM, global 'vdevt' is set to 1.
if there is an unidentified user procedure at the EMM
interrupt, a 2 is returned in 'vdevt'.
If there is no interrupt 0x67 driver installed, exit(9)
is taken after printing an explanatory msg.
*/
static chkout()
{
char *name ;
if (emmchk()) {
vdevt = 1;
name = "EMM supervisor" ;
}
else if (vecchk()) {
vdevt = 2;
name = "user routine on EMM vector" ;
}
else {
printf("There's no software driver for INT 0x67, the EMM vector.\n");
exit(9);
}
printf("Detected %s.\n",name) ;
}
static getstatus()
{
regs.x.ax = 0x4000 ; /* 40h GET STATUS */
int86(0x67, ®s, ®s) ;
if (regs.h.ah) usrexit(0x40,(int)(regs.h.ah)) ;
else {
printf("Status OK.\n");
}
}
static getpfba()
{
regs.x.ax = 0x4100 ; /* 41h GET PFBA */
int86(0x67, ®s, ®s) ;
if (regs.h.ah) usrexit(0x41,(int)(regs.h.ah)) ;
else {
printf("PFBA is at %04x.\n",emm_pfba=regs.x.bx);
}
}
static getsize()
{
regs.x.ax = 0x4200 ; /* 42H GET SIZE */
int86(0x67, ®s, ®s) ;
if (regs.h.ah) usrexit(0x42,(int)(regs.h.ah)) ;
else {
printf("Total size is %d pages\n",totalp=regs.x.dx);
printf("Free size is %d pages\n",freep=regs.x.bx);
}
}
static getver()
{
regs.x.ax = 0x4600 ; /* 46h GET VER. */
int86(0x67, ®s, ®s) ;
if (regs.h.ah) usrexit(0x46,(int)(regs.h.ah)) ;
else {
printf("EMM Version # %02x\n",(char)regs.h.al);
}
}
static aloc(i)
int i ;
{
unsigned usedp ;
regs.x.ax = 0x4300 ; /* 43h ALLOCATE */
usedp = (freep+1)>>1 ; /* Take half of what's avail. */
regs.x.bx = usedp ;
int86(0x67, ®s, ®s) ;
if (regs.h.ah) usrexit(0x43,(int)(regs.h.ah)) ;
else {
printf("%d pages allocated to handle %d\n",
tusedp[i]=usedp,(thandle[i]=(regs.x.dx))) ;
freep -= usedp ;
}
}
static de_aloc(i)
int i ;
{
unsigned npgs ;
regs.h.ah = (char)0x4c ; /* 4ch get EMM handle pages */
regs.x.dx = thandle[i];
int86(0x67, ®s, ®s) ;
if (regs.h.ah) usrexit(0x4c,(int)(regs.h.ah)) ;
npgs = regs.x.bx ;
if (npgs != tusedp[i]) { /* These should be the same ! */
printf("VEMM-reported pages for handle %d not same as applications (%d,%d)\n",
thandle[i], npgs, tusedp[i] );
usrexit(0x4c,0x80) ;
}
regs.h.ah = (char)0x45 ; /* 45h DE-ALLOCATE */
regs.x.dx = thandle[i];
int86(0x67, ®s, ®s) ;
if (regs.h.ah) usrexit(0x45,(int)(regs.h.ah)) ;
else {
printf("[%d] H=%d freed; %d pages.\n",i,thandle[i],npgs) ;
freep += npgs ;
thandle[i] = 0;
tusedp[i] = 0;
}
}
static prt_map()
{
if (vdevt!=2) return ; /* Don't do unless is user interrupt */
regs.x.ax = 0x3F00 ; /* Print Map */
int86(0x67, ®s, ®s) ;
if (regs.h.ah) {
usrexit(0x3f,(int)(regs.h.ah)) ;
}
}
static usrexit(num,rc)
int num, rc;
{
int k ;
printf("EMM[0x%02x] R(0x%02x); Continue(Y/N)? ", num, rc);
while(kbhit()) getch();
do {
while(!kbhit());
k = getch() ;
if ((k=toupper(k))=='\r') break;
} while(k!='Y' && k!='N') ;
printf("%c\n",k);
if (k=='N') exit(1000) ;
}
static more()
{
printf("\r--more--") ;
while(!kbhit()) ;
while(kbhit()) getch() ;
printf("\r \r");
}
static emm_map(handle, page, window)
int handle, page, window ;
{
regs.h.ah = 0x44 ; /* Map Handle Pages */
regs.h.al = (char)(window) ;
regs.x.dx = handle ;
regs.x.bx = page ;
int86(0x67, ®s, ®s) ;
if (regs.h.ah) {
usrexit(0x44,(int)(regs.h.ah)) ;
}
}
static use_emm(hslot,size)
int hslot, size;
{
char message[255] ;
unsigned i, j, o ;
printf("Writing %d sprintf strings to expanded memory handle=%d at segment %04x\n",
size,thandle[hslot],emm_pfba);
for (o=j=i=0; i<size; i++, j++, o+=0x4000 ) {
if (j>3) { o = j = 0 ; } /* NOTE: ASSUMES ALL 4 WINDOWS OK TO USE! */
sprintf(message,"Hello, from page %d, in window %d (@%04x:%04x)",
i,j,emm_pfba,o);
emm_map(thandle[hslot],i,j);
poke(emm_pfba,o,message,sizeof(message));
}
printf("Strings have been written.\n");
printf("Reading Strings from EMM buffer:\n");
for (o=j=i=0; i<size; i++, j++, o+=0x4000 ) {
if (j>3) { o = j = 0 ; }
emm_map(thandle[hslot],i,j);
peek(emm_pfba,o,message,sizeof(message));
printf("msg[%d.%d]='%s'.\n",i,j,message);
}
}