home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_02_11
/
2n11027a
< prev
next >
Wrap
Text File
|
1991-09-13
|
5KB
|
171 lines
/* ----------------------------------------------------
* LISTING 6
*
* Filename: emm.c
* Summary: Expanded memory interface
* functions for BCACHE manager
* Author: T.W. Nelson
* Compile options:
* Version: 1.00
* Date: 09-Sep-1991
* Notes:
*
* Source code Copyright (c) 1991 T.W. Nelson. May be
* used only for non-commercial purposes with
* appropriate acknowledgement of copyright.
* ------------------------------------------------- */
#include "bcache.h"
#pragma inline
static char EMM_dev[] = "EMMXXXX0";
static int EMM_flag = 1; //run-time emm usage switch
//... default is ENABLED
#define handle user1 //rename user data areas
#define npages user2 //in BCACHE object
void emm_setflag( int flag )
{
/* Turn expmem usage on/off. */
EMM_flag = flag;
}
void emm_map_pages( BCACHE *cp )
{
/* Save current EMM page-mapping context, then
* map our cache pages into the physical page frame.
*/
size_t emm_handle, pages;
asm cmp EMM_flag,0 //expmem in use?
asm je map_x //no, bypass
emm_handle = cp->handle;
pages = cp->npages;
asm mov ah,47h //EMS save page map
asm mov dx,emm_handle
asm int 67h
asm mov cx,pages //set loop counter
asm xor bx,bx //start at logpage 0
map_in:
asm mov ah,44h //EMS map expmemory page
asm mov al,bl //set physpage
asm int 67h
asm inc bx //to next logpage
asm loop map_in
map_x:
return;
}
void emm_unmap_pages( BCACHE *cp )
{
/* Restore page mapping context ... */
size_t emm_handle;
asm cmp EMM_flag,0 //expmem in use?
asm je unmap_x //no, bypass
emm_handle = cp->handle;
asm mov ah,48h //EMS restore page map
asm mov dx,emm_handle
asm int 67h
unmap_x:
return;
}
int emm_allocate( BCACHE *cp, int flag )
{
/* Allocate expanded memory for the block cache.
* Called by bc_open() if using expmemory.
*/
chdr_t *page_frame;
size_t pages_needed, bytes_mem, emm_handle;
asm cmp flag,ALLOCATE //allocate?
asm jne emmalloc_4 //no, deallocate
bytes_mem = (cp->bsiz+BHDR_SIZE) * cp->bmax;
asm mov ax,bytes_mem //set dividend loword
asm mov dx,0 //clear dividend hiword
asm mov bx,16384 //16k page size divisor
asm div bx //ax == number pages
asm or ax,ax //0 quotient?
asm jz emmalloc_1 //yes, adjust
asm or dx,dx //any remainder?
asm jz emmalloc_2 //no, bypass
emmalloc_1:
asm inc ax //adjust for remainder
emmalloc_2:
asm cmp ax,4 //check page request
asm ja emmalloc_3 //too many pages
asm mov pages_needed,ax
asm mov ah,41h //EMS get page frame seg
asm int 67h
asm mov word ptr page_frame[2],bx
asm mov word ptr page_frame[0],0
asm mov bx,pages_needed
asm mov ah,43h //EMS allocate pages
asm int 67h
asm or ah,ah //allocated?
asm jnz emmalloc_3 //no, quit
asm mov bytes_mem,dx //save emm handle
cp->handle = bytes_mem;
cp->npages = pages_needed;
cp->head = page_frame;
goto emmalloc_5;
emmalloc_4: //deallocate memory
emm_handle = cp->handle;
asm mov ah,45h //EMS release handle
asm mov dx,emm_handle
asm int 67h
emmalloc_5:
return BC_NOERROR;
emmalloc_3:
return BC_NOMEMORY;
}
int emm_check( void )
{
/* Test for presence of functioning EMM.
* If EMM not available, 'EMM_flag' is reset to
* OFF (== 0). Function returns 0 if EMM is
* available and functioning, -1 if not or
* 'EMM_flag' is OFF.
*/
asm cmp EMM_flag,0 //use expmem?
asm je emm_error //no, return error
asm push ds
asm mov dx,offset EMM_dev
asm mov ax,seg EMM_dev
asm mov ds,ax
asm mov ax,3d00h //DOS open file, read only
asm int 21h
asm pop ds
asm jc emm_error //EM driver not present
asm mov bx,ax //bx <- open device handle
asm mov ax,4407h //DOS IOCTL device status
asm int 21h
asm jc emm_error //IOCTL failure
asm or al,al //device ready?
asm jz emm_error //al == 0 if not
asm mov ah,3eh //DOS close handle
asm int 21h
asm mov ah,40h //check EMM status
asm int 67h
asm or ah,ah //op status OK?
asm jnz emm_error //no, exit
return 0; //return EMM OK
emm_error:
emm_setflag(0); //disable EMM usage
return -1;
}
/* ---- End of File -------------------------------- */