home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware 1 2 the Maxx
/
sw_1.zip
/
sw_1
/
PROGRAM
/
EMS_SUBS.ZIP
/
EMS-SUBS.MSG
Wrap
Text File
|
1992-01-02
|
7KB
|
329 lines
Path: rutgers!ucsd!ames!killer!royf
From: royf@killer.Dallas.TX.US (Roy Frederick)
Newsgroups: comp.sys.ibm.pc
Subject: EMS Routines for TurboC
Date: 23 Apr 89 17:56:03 GMT
Keywords: EMS TURBOC
These EMS access routines are in the public domain - no secrets,
copyrights, or restrictions on use. There really isn't much to them -
but I use them in production data collection programs that run every
day (at least I think these are the versions I am currently using!).
Three routines are included: Emstest.c, emstbl.c, emssubr.asm. Also a
header file etbl.h. Emssubr.asm provides the lowest level access to
EMS. It is called by emstbl.c to provide access to tables of fixed
length items with a total length limited by the amount of EMS present.
The length of a single table item is limited to <= 16384 (EMS page
length). Space beyond the last item in an EMS page is wasted.
Emstest.c demonstrates the use of emstbl.c. The routines are set up
for large model.
C routines have 4 col tabs; ASM , 8
Etbl.h -------------------------------------------------------------
/*
* Etbl.h -- Structure describing table in EMS
*/
struct etbl {
int e_elen; /* Table entry length */
int e_ecnt; /* Table entry count */
int e_efrm; /* Frame to be used */
int e_ecur; /* Last assigned entry number */
int e_ecpf; /* Entry count per page */
int e_pgs; /* Pages allocated */
int e_hand; /* EMS Handle */
} ;
void far * far etmap(struct etbl far *, int);
int far etinit(struct etbl far *);
void far etclose(struct etbl far *);
Emstest.c --------------------------------------------------------------------
/*
* Emstest.c -- EMS Table Routines Test Pgm
*/
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "etbl.h"
struct etbl et1 = { 100, 1000, 1, 0, 0, 0 } ;
main()
{
int i;
int far *q;
etinit(&et1);
for (i = 1; i <= 1000; i++) {
q = etmap(&et1, i);
if (q == 0L)
err("Etmap failed for %d", i);
*q = i;
}
for (i = 1; i <= 1000; i++) {
q = etmap(&et1, i);
if (q == 0L)
err("Etmap failed for %d", i);
if (*q != i)
err("Data error - exp %d got %d", i, *q);
}
etclose(&et1);
err("Test successful");
}
err(s)
const char *s;
{
va_list argptr;
va_start(argptr, s);
fprintf(stderr, "Terminated: ");
vfprintf(stderr, s, argptr);
fprintf(stderr, "\n");
exit(2);
}
Emstbl.c ----------------------------------------------------------------
/*
* Emstbl -- EMS Table Routines
*/
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "etbl.h"
static int eseg; /* EMS Segment Address */
extern int ems_err;
int far etinit(e)
struct etbl far *e;
{
int i;
if (ems_verify() == 0)
err("No EMS driver found");
eseg = ems_getframe();
e->e_ecpf = 16384 / e->e_elen;
e->e_pgs = (e->e_ecnt + e->e_ecpf - 1) / e->e_ecpf;
e->e_ecnt = e->e_pgs * e->e_ecpf;
if ((e->e_hand = ems_alloc(e->e_pgs)) == 0)
err("Not enough EMS available");
for (i = 0; i < e->e_pgs; i++) {
if (ems_map(e->e_efrm, e->e_hand, i) == 0)
err("EMS_MAP failed err %02x handle %04X page %02X",
ems_err, e->e_hand, i);
memset(MK_FP(eseg, (e->e_efrm << 14)), 0, 16384);
}
e->e_ecur = 0;
return(0);
}
void far * far etmap(e, ndx)
struct etbl far *e;
int ndx;
{
int i, j, pg;
j = ndx - 1;
i = j / e->e_ecpf;
j = j % e->e_ecpf;
pg = e->e_efrm;
if (ems_map(pg, e->e_hand, i) == 0)
err("EMS_MAP failed err %02x handle %04X page %02X",
ems_err, e->e_hand, i);
return(MK_FP((eseg + (pg << 10)), (j * e->e_elen)));
}
void far etclose(e)
struct etbl far *e;
{
ems_free(e->e_hand);
e->e_elen = e->e_ecur = e->e_ecnt = e->e_hand = 0;
}
Emssubr.asm -----------------------------------------------------------
----assemble with TASM /W2 /MX emssubr -------------------------------
PAGE ,132
TITLE Expanded Memory Access Routines
.MODEL LARGE,C
PUBLIC ems_err
PUBLIC ems_verify
PUBLIC ems_alloc
PUBLIC ems_map
PUBLIC ems_free
PUBLIC ems_getframe
PUBLIC ems_pagecnt
LOCALS LL
.DATA
emname db 'EMMXXXX0' ; name of ems driver
ems_err dw 0
.CODE
SUBTTL ems_verify
PAGE +
ems_verify PROC uses DS SI DI
mov ax, DGROUP
mov ds, ax
mov ax, 0 ; check if int vect 67 set up
mov es, ax
mov ax, es:[4*67h+2]
or ax, ax ; segment non zero ?
jz LL01 ; if not
mov es, ax
mov di, 10 ; offset to driver name
mov si, offset emname
mov cx, 8
cld
rep cmpsb ; check driver name
jne LL01
mov ax, 1
jmp short LL02
LL01: mov ax, 0ffh ; no driver code
mov [ems_err], ax
xor ax, ax ; zero ret code = bad
LL02: ret
ems_verify ENDP
SUBTTL ems_alloc
PAGE +
ems_alloc PROC uses DS
arg pgcnt:word
mov ax, DGROUP
mov ds, ax
mov bx, [pgcnt] ; get number of pages to allocate
mov ah, 43H ; allocate space
int 67H
mov byte ptr [ems_err], ah
or ah, ah ; ah is zero if call succeeded
jnz LL01
mov ax, dx ; return handle
jmp short LL02
LL01:
xor ax, ax
LL02:
ret
ems_alloc ENDP
SUBTTL ems_map
PAGE +
ems_map PROC uses DS
arg phys:word,handle:word,lpage:word
mov ax, DGROUP
mov ds, ax
mov ax, [phys] ; get phys page slot
mov dx, [handle] ; get handle number
mov bx, [lpage] ; get logical page number
mov ah, 44H ; map page
int 67H
mov byte ptr [ems_err], ah
or ah, ah ; see if ok
jnz LL01
mov ax, 1
jmp short LL02
LL01:
xor ax, ax
LL02:
ret
ems_map ENDP
SUBTTL ems_free
PAGE +
ems_free PROC
arg handle:word
mov dx, [handle]
mov ah, 45H
int 67H
xor ax, ax
ret
ems_free ENDP
SUBTTL ems_getframe
PAGE +
ems_getframe PROC uses DS ; sets AX to EMS page frame
mov ax, DGROUP
mov ds, ax
mov ah, 41H ; get frame seq
int 67H
mov byte ptr [ems_err], ah
or ah, ah ; ah is zero if call succeeded
jnz LL01
mov ax, bx ; return page frame in ax
jmp short LL02
LL01:
xor ax, ax
LL02:
ret
ems_getframe ENDP
SUBTTL ems_pagecnt
PAGE +
ems_pagecnt PROC uses DS ; sets AX to EMS page frame
mov ax, DGROUP
mov ds, ax
mov ah, 42H ; get ems page count
int 67H
mov byte ptr [ems_err], ah
or ah, ah ; see if ok
jnz LL01
mov ax, bx ; return page count
jmp short LL02
LL01:
xor ax, ax
LL02:
ret
ems_pagecnt ENDP
END
-----------------------------------------------------------------------------
Roy Frederick (royf@killer.UUCP)
Dallas County Data Services (214) 749-6340
504 Records Bldg.
Dallas, TX 75202