This is xms.c in view mode; [Download] [Up]
/* ** xms.c -- C bindings for xms API - implemented ** Author: Kent Williams william@umaxc.weeg.uiowa.edu */ #pragma inline #include <stdio.h> #include <stdlib.h> #include "xms.h" static void far xms_spoof(void); static void (far *xms_entry)(void) = xms_spoof; char xms_error; int xms_installed(void) { asm mov ax,0x4300 /* get installation status */ asm int 0x2f /* call driver */ asm mov ah,1 /* return true if present */ asm cmp al,0x80 /* are you there? */ asm je __present asm xor ax,ax /* no, return false */ __present: asm xchg ah,al /* if present, set ax to 1 */ asm cbw return _AX; } static void xms_get_entry(void) { asm mov ax,0x4310 /* get driver entry */ asm int 0x2f /* call multiplex */ asm mov word ptr xms_entry,bx asm mov word ptr (xms_entry+2),es } static void far xms_spoof(void) { asm push ax asm push bx asm push cx asm push dx asm push si asm push di asm push es asm push ds if(!xms_installed()) { fputs("No XMS driver installed\n",stderr); exit(1); } else xms_get_entry(); asm pop ds asm pop es asm pop di asm pop si asm pop dx asm pop cx asm pop bx asm pop ax xms_entry(); } xms_version_info * xms_get_version_info(void) { unsigned xms_ver,xmm_ver,hma_indicator; static xms_version_info x; asm xor ah,ah asm call [xms_entry] asm mov xms_error,bl asm mov xms_ver,ax asm mov xmm_ver,bx asm mov hma_indicator,dx xms_ver = (xms_ver & 0xf) + (((xms_ver >> 4) & 0xf) * 10) + ((xms_ver >> 8) & 0xf) * 100 + ((xms_ver >> 12) & 0xf) * 1000; xmm_ver = (xmm_ver & 0xf) + (((xmm_ver >> 4) & 0xf) * 10) + ((xmm_ver >> 8) & 0xf) * 100 + ((xmm_ver >> 12) & 0xf) * 1000; x.xms_ver = xms_ver; x.xmm_ver = xmm_ver; x.hma_present = hma_indicator; return &x; } xms_extended_info * xms_query_extended_memory(void) { unsigned max_free_block,total_extended_memory; static xms_extended_info x; asm mov ah,0x8 asm call [xms_entry] asm mov xms_error,bl asm mov max_free_block,ax asm mov total_extended_memory,dx x.max_free_block = max_free_block; x.total_extended_memory = total_extended_memory; return &x; } int xms_hma_allocate(unsigned siz) { asm mov ah,0x01 asm mov dx,word ptr siz asm call [xms_entry] asm mov xms_error,bl /* xms returns 1 on success, 0 on failure. We need to invert this ** for the C idiom. ** if ax = 1 then not ax = 0xfffe and add ax,2 = 0 ** if ax = 0 then not ax = 0xffff and add ax,2 = 1 */ asm not ax asm inc ax asm inc ax return _AX; } int xms_hma_free(void) { asm mov ah,0x02 asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } int xms_global_enable_a20(void) { asm mov ah,0x03 asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } int xms_global_disable_a20(void) { asm mov ah,0x4 asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } int xms_local_enable_a20(void) { asm mov ah,0x5 asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } int xms_local_disable_a20(void) { asm mov ah,0x6 asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } int xms_a20_status(void) { asm mov ah,0x7 asm call [xms_entry] asm mov xms_error,bl return _AX; } int xms_emb_allocate(emb_size_K_t siz) { asm mov ah,0x9 asm mov dx,siz asm call [xms_entry] asm mov xms_error,bl asm or ax,ax /* allocation succeed? */ asm jz alloc_failed /* no, return 0 */ asm xchg ax,dx /* yes, return handle */ asm jmp done alloc_failed: asm mov ax,-1 done:; return _AX; } int xms_emb_free(emb_handle_t handle) { asm mov ah,0x0a asm mov dx,handle asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } emb_handle_info * xms_get_emb_handle_info(emb_handle_t handle) { static emb_handle_info info; unsigned char locks,handles; emb_size_K_t siz; asm mov ah,0x0e asm mov dx,handle asm call [xms_entry] asm or ax,ax /* did call fail? */ asm jz call_failed asm mov locks,bh asm mov handles,bl asm mov siz,dx asm jmp short done call_failed: asm mov xms_error,bl asm mov ax,1 asm mov word ptr siz,-1 done: info.lock_count = locks; info.handles_available = handles; info.block_size = siz; return siz == 0xffff ? NULL : &info; } int xms_emb_resize(emb_handle_t handle,emb_size_K_t siz) { asm mov ah,0xf asm mov bx,siz asm mov dx,handle asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } int xms_move_emb(xms_move_param *x) { xms_move_param far *x2 = (xms_move_param far *)x; asm push ds asm mov ah,0xb asm lds si,x2 asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } emb_off_t xms_lock_emb(emb_handle_t handle) { asm mov ah,0x0c asm mov dx,handle asm call [xms_entry] asm cmp ax,0 asm je lock_failed asm mov ax,bx /* return value in dx:ax */ asm mov xms_error,0 asm jmp lock_done lock_failed: asm mov dx,ax asm mov xms_error,bl lock_done: ; asm pop bp /* these do the actual returning, */ asm ret /* the return below is to satisfy tcc */ return 0; /* we can't tell tcc that we filled DX:AX for return, so we fake it to silence the warning */ } int xms_unlock_emb(emb_handle_t handle) { asm mov ah,0x0d asm mov dx,handle asm call [xms_entry] asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; } umb_info * xms_umb_allocate(umb_size_t siz) { static umb_info x; unsigned segment,block_size; asm mov ah,0x10 asm mov dx,siz asm call [xms_entry] asm mov xms_error,bl asm mov segment,bx asm mov block_size,dx asm or ax,ax asm jnz done asm mov segment,ax done: x.segment = segment; x.block_size = block_size; return segment != 0 ? &x : NULL; } int xms_umb_free(umb_segment_t segment) { asm mov ah,0x11 asm mov dx,segment asm call [xms_entry]; asm mov xms_error,bl asm not ax asm inc ax asm inc ax return _AX; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.