home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
BLTC13A.ZIP
/
BORLAND.ZIP
/
MEMCXB.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-07-22
|
12KB
|
233 lines
TITLE MEMCXB ;C version
PAGE 55,132
;multiple routines
;xb$malloc
;xb$free
;xb$SetHandleCount (no longer available with this replacement module)
;-----------------------------------------------------------------------|
; ScanSoft (C)1992 Cornel H Huth ALL RIGHTS RESERVED |
;-----------------------------------------------------------------------|
; date: 30-Sep-92 |
; function: Memory routines for C compilers |
; that do not allow DOS allocations to be mixed with |
; _malloc allocations (including _calloc, etc.) |
; notes: This malady afflicts Borland C compilers |
; All registers saved since there's no telling what |
; registers the runtime code uses (ax,bp not saved) |
; |
; |
;The code below will work in either LARGE or HUGE memory modules. |
;It will not, as written, work in the medium model. With minor changes, |
;the medium model could be supported. |
; |
;This code was written with MASM 5.10A in mind though TASM should |
;handle it, too. |
; |
;To assemble: |
; |
; C>masm memcxb /mx; (/mx=preserve case on globals) |
; |
;You can then use either of the following methods: |
; |
; Replace MEMXB.OBJ in BULLET.LIB: |
; |
; C>lib BULLET -memxb +memcxb; |
; |
; Or, leave BULLET.LIB as is but place MEMCXB.OBJ on the link line with |
; the other object modules. This will, however, cause the linker to |
; issue the warning "DUPLICATE SYMBOL DEFINITION". This is expected. |
; The linker will use the code in MEMCXB.OBJ and ignore the memxb module|
; in BULLET.LIB. |
; |
;-----------------------------------------------------------------------|
WPTR EQU <WORD PTR>
.MODEL LARGE,PASCAL
.CODE
EXTRN _malloc:FAR
EXTRN _free:FAR
;The Tracker lists are allocated in code segment to minimize
;impact on DGROUP
;MAXTRACKER is the number of allocations that can be open at
;any one time. Consider each open file to require one Track.
;A good MAXTRACKER value would be the total number of files you
;require to be open at one time plus 5. Each MAXTRACKER
;requires 6 bytes of code space. Unless you're starving for
;RAM, MAXTRACKER is fine at 254 (uses about 1.5K of code space.)
MAXTRACKER EQU 254
;TrackerFP stores far pointers as returned by _malloc
;so that _free can be used (_free requires exact FP match)
EVEN
TrackerFP dd MAXTRACKER DUP (0) ;32-bit pointer as returned by _malloc
dd 0 ;and required by _free
;TrackerSeg stores the 16-bit segment pointer converted from
;the far pointer returned by _malloc. See xb$malloc for how
;this is done. This is used as a lookup value in xb$free.
TrackerSeg dw MAXTRACKER DUP (0) ;thunk it to a 16-bit segment pointer
dw -1
;-----------------------------------------------------------------------|
; date: 30-Sep-92 |
; function: allocate memory |
; caller: FAR, ASSEMBLY |
; stack: n/a |
; in: bx=paragraphs to allocate |
; out: NC=ax=seg |
; CY=ax=8=not enough memory |
; uses: ax (return),bx |
; notes: call with bx=FFFF and bx returns w/ largest block free |
; (according to DOS) |
;chh: removed bx save on xb$malloc |
;-----------------------------------------------------------------------|
XB$MALLOC PROC USES cx dx si di es ds
cmp bx,-1 ;just asking for available memory?
jne xb$malloc01 ;no
mov ah,48h ;yes
int 21h
jmp SHORT xb$mallocXit
xb$malloc01: mov cx,MAXTRACKER ;scan for next free descriptor
sub ax,ax ;0 indicates available
push cs
mov di,OFFSET TrackerSeg
pop es ;es:di->TrackSeg start
repne scasw
jne xb$mallocEx ;none available
mov ax,di
sub ax,OFFSET TrackerSeg+2 ;ax=available slot (word)
push ax ;save slot
sub ax,ax
push ax ;high-word of request
mov ax,bx ;paras requested
inc ax ;bump para request so we can norm it
shl ax,1 ;(thunk it would be more like it)
shl ax,1
shl ax,1
shl ax,1 ;paras to bytes
push ax ;low-word of request
call _malloc ;appease the Borland Gods
add sp,4 ;here dx:ax is far pointer to block
pop di ;get back slot
mov bx,dx ;check for null pointer return
or bx,ax ;allocation okay?
jz xb$mallocEx ;no
mov si,di ;word slot index for TrackerSeg
shl di,1 ;dword slot index for TrackerFP
mov WPTR cs:[TrackerFP+di],ax
mov WPTR cs:[TrackerFP+di+2],dx
;normalize the 32-bit pointer to a 16-bit segment pointer
;we can do this because we requested 1 additional paragraph
;so that we can just drop the normalized offset and start
;using the allocated memory block at the next paragraph
;;since we won't be using the fractional-para offset of the
;;norm'ed far pointer we can skip the overhead
;;mov bx,ax ;save full offset
;;and ax,000Fh ;non-paragraph portion
;;mov cx,ax ;ax is normalized offset
;;mov ax,bx ;get full offset back
shr ax,1 ;convert offset to full paras
shr ax,1
shr ax,1
shr ax,1
add ax,dx ;add segment in
inc ax ;bump to next paragraph
mov cs:[TrackerSeg+si],ax
clc ;return 16-bit segment pointer in ax
xb$mallocXit: ret ;that BULLET will use
xb$mallocEx: mov ax,8
stc
jmp SHORT xb$mallocXit
XB$MALLOC ENDP
;-----------------------------------------------------------------------|
; date: 30-Sep-92 |
; function: free allocated memory |
; caller: FAR, ASSEMBLY |
; stack: n/a |
; in: es=segment pointer of block to free |
; out: NC=okay (at least this code, _free has not return code)|
; CY=ax=9 invalid block (segment not in descriptor list |
; uses: ax (return) |
; notes: see xb$malloc above for more info |
;-----------------------------------------------------------------------|
XB$FREE PROC USES bx cx dx si di ds es
mov cx,MAXTRACKER ;scan for matching descriptor
mov ax,es ;search for this segment pointer
push cs
mov di,OFFSET TrackerSeg
pop es ;es:di->TrackerSeg start
repne scasw
jne xb$freeEx ;not found, must be invalid block
sub ax,ax
sub di,OFFSET TrackerSeg+2 ;di=matched slot (word)
push di ;save slot
shl di,1 ;dword slot index
push WPTR cs:[TrackerFP+di+2];segment to block to release
push WPTR cs:[TrackerFP+di] ;offset
call _free ;appease them some more
add sp,4
sub ax,ax
mov WPTR cs:[TrackerFP+di+2],ax ;clear descriptor info
mov WPTR cs:[TrackerFP+di],ax
pop di ;get word slot index
mov cs:[TrackerSeg+di],ax ;make slot available
xb$freeXit: ret
xb$freeEx: mov ax,9
stc
jmp xb$freeXit
XB$FREE ENDP
;-----------------------------------------------------------------------|
; date: 30-Sep-92 |
; function: set maximum handle count |
; caller: FAR, ASSEMBLY |
; stack: n/a |
; in: bx=handle count |
; out: NC=okay |
; CY=ax=error number |
; uses: ax (return) |
; notes: Cannot use DOS INT21/67 since it makes a DOS memory |
; allocation call which, as you know, cannot be |
; issued when using Borland's _malloc functions. |
;-----------------------------------------------------------------------|
XB$SETHANDLECOUNT PROC
mov ax,1 ;function not available for Borland C
stc ;via this route
ret
XB$SETHANDLECOUNT ENDP
END