home *** CD-ROM | disk | FTP | other *** search
- title global storage functions
- include asm.inc
-
-
- public global_alloc
- public global_calloc
- public global_free
- public global_lock
- public global_realloc
- public global_unlock
-
-
-
- GLOBAL_MAX equ 100 ; maximum number of storage handles
- NULL_HANDLE equ 0
-
-
- global_str struc
- g_address dd ? ; storage address
- g_lock dw ? ; storage lock count
- g_size dw ? ; size of storage
- global_str ends
-
-
- .data?
-
- global_count dw ? ; number of allocated handles
- global_table global_str GLOBAL_MAX dup(<>)
-
-
- .code
- extn calloc,clear_strerror,free,malloc,realloc
-
-
- ;; global alloc
- ;
- ; entry CX requested size
- ; exit AX actual size
- ; BX storage handle (never zero)
- ; Cf if no storage
- ;
- global_alloc proc
- pushm di,es
- call malloc
- jc gal1 ; if not enough memory
- call global_alloc_common
- gal1: popm es,di
- ret
- global_alloc endp
-
-
- ;; global alloc common
- ;
- ; entry AX storage size
- ; ES:DI storage pointer
- ; exit BX storage handle
- ; Cf if out of handles
- ;
- global_alloc_common proc
- pushm ax,dx,cx,si,ds
- mov dx,ax
-
- mov bx,GLOBAL_MAX
- mov cx,bx
- cmp cx,global_count[bp]
- jbe gac2 ; if out of handles
-
- mov si,@data
- mov ds,si
- lea si,global_table-size global_str
-
- gac1: add si,size global_str ; search for first free handle (SLOW!)
- mov ax,wptr g_address[si]
- or ax,wptr g_address[si+2]
- loopnz gac1
- jnz gac2 ; if unexpected error: corrupted data
-
- mov g_lock[si],ax
- mov g_size[si],dx
- mov wptr g_address[si],di
- mov wptr g_address[si+2],es
- inc global_count[bp]
-
- sub bx,cx ; compute non-zero handle 1..n (Cf=0)
- gac2: popm ds,si,dx,cx,ax
- ret
-
- gac3: stc
- jmp gac2
- global_alloc_common endp
-
-
- ;; global calloc
- ;
- ; entry CX requested size
- ; exit AX actual size
- ; BX storage handle (never zero)
- ; Cf if no storage
- ;
- global_calloc proc
- pushm di,es
- call calloc
- jc gca1 ; if not enough memory
- call global_alloc_common
- gca1: popm es,di
- ret
- global_calloc endp
-
-
- ;; global free
- ;
- ; entry BX storage handle (OK if zero)
- ; exit BX 0
- ; uses AX
- ;
- global_free proc
- pushm di,es
- cmpx bx,NULL_HANDLE
- je gfr1 ; if NULL handle, just return
- call read_global_entry
- mov bx,NULL_HANDLE
- jc gfr1 ; if bad handle
-
- les di,g_address[si]
- call free
- mov wptr g_address[si],di
- mov wptr g_address[si+2],es
-
- gfr1: popm es,di
- ret
- global_free endp
-
-
- ;; global lock
- ;
- ; entry BX valid storage handle
- ; exit DS:SI storage pointer
- ; note DOES NOT BASH AX
- ;
- global_lock proc
- call read_global_entry
- jc glk1 ; if bad handle
- inc g_lock[si]
- lds si,g_address[si]
- glk1: ret
- global_lock endp
-
-
- ;; global realloc
- ;
- ; entry BX storage handle
- ; CX new size
- ; exit AX actual size (if no errors)
- ; Cf if not enough memory
- ;
- global_realloc proc
- pushm di,si,ds,es
- call read_global_entry
- jc gre1 ; if bad handle
-
- les di,g_address[si]
- call realloc
- jnc gre1 ; if realloc OK
-
- mov ax,g_lock[si] ; check lock count before moving
- add ax,-1
- jc gre1 ; if locked, cannot move
- call clear_strerror ; else clear realloc error
-
- call malloc
- jc gre1 ; if no memory
-
- pushm ax,di,es ; copy old storage to new storage
- pushm cx,si,ds
- mov cx,g_size[si]
- lds si,g_address[si]
- rep movsb
- popm ds,si,cx
-
- les di,g_address[si] ; free old storage
- call free
- popm es,di,ax
-
- mov wptr g_address[si],di ; set new storage pointer and size
- mov wptr g_address[si+2],es
- mov g_size[si],ax
- clc
-
- gre1: popm es,ds,si,di
- ret
- global_realloc endp
-
-
- ;; global unlock
- ;
- ; entry BX valid storage handle
- ; note flags do NOT change
- ;
- global_unlock proc
- pushf
- pushm si,ds
- call read_global_entry
- jc gun1 ; if bad handle
- dec g_lock[si]
- gun1: popm ds,si
- popf
- ret
- global_unlock endp
-
-
- ;; read global entry
- ;
- ; entry BX global handle
- ; exit DS:SI global table for handle
- ; Cf if bad handle
- ;
- read_global_entry proc
- pushm ax,dx
- mov ax,@data
- mov ds,ax
- lea si,global_table
-
- cmp bx,GLOBAL_MAX
- ja rge1 ; if bad handle
-
- mov ax,bx ; multiply handle by structure size
- dec ax ; to select global table entry
- mov dx,size global_str
- mul dx
- add si,ax
- rge1: popm dx,ax
- ret
- read_global_entry endp
-
- end
-