Category : Utilities for DOS and Windows Machines
Archive   : VEUM.ZIP
Filename : TEST67H.C

 
Output of file : TEST67H.C contained in archive : VEUM.ZIP

/*

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
#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 aloc(i) ;
prt_map() ;
}

getsize() ;

for (i=0;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 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 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);
}

}