home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / progjour / 1991 / 03 / global.asm < prev    next >
Assembly Source File  |  1991-02-22  |  4KB  |  236 lines

  1.     title    global storage functions
  2.     include    asm.inc
  3.  
  4.  
  5.     public    global_alloc
  6.     public    global_calloc
  7.     public    global_free
  8.     public    global_lock
  9.     public    global_realloc
  10.     public    global_unlock
  11.  
  12.  
  13.  
  14. GLOBAL_MAX        equ    100    ; maximum number of storage handles
  15. NULL_HANDLE        equ    0
  16.  
  17.  
  18. global_str struc
  19.   g_address        dd  ?        ; storage address
  20.   g_lock        dw  ?        ; storage lock count
  21.   g_size        dw  ?        ; size of storage
  22. global_str ends
  23.  
  24.  
  25.     .data?
  26.  
  27. global_count    dw    ?        ; number of allocated handles
  28. global_table    global_str    GLOBAL_MAX dup(<>)
  29.  
  30.  
  31.     .code
  32.     extn    calloc,clear_strerror,free,malloc,realloc
  33.  
  34.  
  35. ;;    global alloc
  36. ;
  37. ;    entry    CX    requested size
  38. ;    exit    AX    actual size
  39. ;        BX    storage handle (never zero)
  40. ;        Cf    if no storage
  41. ;
  42. global_alloc proc
  43.     pushm    di,es
  44.     call    malloc
  45.     jc    gal1            ;  if not enough memory
  46.     call    global_alloc_common
  47. gal1:    popm    es,di
  48.     ret
  49. global_alloc endp
  50.  
  51.  
  52. ;;    global alloc common
  53. ;
  54. ;    entry    AX    storage size
  55. ;        ES:DI    storage pointer
  56. ;    exit    BX    storage handle
  57. ;        Cf    if out of handles
  58. ;
  59. global_alloc_common proc
  60.     pushm    ax,dx,cx,si,ds
  61.     mov    dx,ax
  62.  
  63.     mov    bx,GLOBAL_MAX
  64.     mov    cx,bx
  65.     cmp    cx,global_count[bp]
  66.     jbe    gac2            ;  if out of handles
  67.  
  68.     mov    si,@data
  69.     mov    ds,si
  70.     lea    si,global_table-size global_str
  71.  
  72. gac1:    add    si,size global_str    ; search for first free handle (SLOW!)
  73.     mov    ax,wptr g_address[si]
  74.     or    ax,wptr g_address[si+2]
  75.     loopnz    gac1
  76.     jnz    gac2            ;  if unexpected error: corrupted data
  77.  
  78.     mov    g_lock[si],ax
  79.     mov    g_size[si],dx
  80.     mov    wptr g_address[si],di
  81.     mov    wptr g_address[si+2],es
  82.     inc    global_count[bp]
  83.  
  84.     sub    bx,cx            ; compute non-zero handle 1..n (Cf=0)
  85. gac2:    popm    ds,si,dx,cx,ax
  86.     ret
  87.  
  88. gac3:    stc
  89.     jmp    gac2
  90. global_alloc_common endp
  91.  
  92.  
  93. ;;    global calloc
  94. ;
  95. ;    entry    CX    requested size
  96. ;    exit    AX    actual size
  97. ;        BX    storage handle (never zero)
  98. ;        Cf    if no storage
  99. ;
  100. global_calloc proc
  101.     pushm    di,es
  102.     call    calloc
  103.     jc    gca1            ;  if not enough memory
  104.     call    global_alloc_common
  105. gca1:    popm    es,di
  106.     ret
  107. global_calloc endp
  108.  
  109.  
  110. ;;    global free
  111. ;
  112. ;    entry    BX    storage handle (OK if zero)
  113. ;    exit    BX    0
  114. ;    uses    AX
  115. ;
  116. global_free proc
  117.     pushm    di,es
  118.     cmpx    bx,NULL_HANDLE
  119.     je    gfr1            ;  if NULL handle, just return
  120.     call    read_global_entry
  121.     mov    bx,NULL_HANDLE
  122.     jc    gfr1            ;  if bad handle
  123.  
  124.     les    di,g_address[si]
  125.     call    free
  126.     mov    wptr g_address[si],di
  127.     mov    wptr g_address[si+2],es
  128.  
  129. gfr1:    popm    es,di
  130.     ret
  131. global_free endp
  132.  
  133.  
  134. ;;    global lock
  135. ;
  136. ;    entry    BX    valid storage handle
  137. ;    exit    DS:SI    storage pointer
  138. ;    note        DOES NOT BASH AX
  139. ;
  140. global_lock proc
  141.     call    read_global_entry
  142.     jc    glk1            ;  if bad handle
  143.     inc    g_lock[si]
  144.     lds    si,g_address[si]
  145. glk1:    ret
  146. global_lock endp
  147.  
  148.  
  149. ;;    global realloc
  150. ;
  151. ;    entry    BX    storage handle
  152. ;        CX    new size
  153. ;    exit    AX    actual size (if no errors)
  154. ;        Cf    if not enough memory
  155. ;
  156. global_realloc proc
  157.     pushm    di,si,ds,es
  158.     call    read_global_entry
  159.     jc    gre1            ;  if bad handle
  160.  
  161.     les    di,g_address[si]
  162.     call    realloc
  163.     jnc    gre1            ;  if realloc OK
  164.  
  165.     mov    ax,g_lock[si]        ; check lock count before moving
  166.     add    ax,-1
  167.     jc    gre1            ;  if locked, cannot move
  168.     call    clear_strerror        ;  else clear realloc error
  169.  
  170.     call    malloc
  171.     jc    gre1            ;  if no memory
  172.  
  173.     pushm    ax,di,es        ; copy old storage to new storage
  174.     pushm    cx,si,ds
  175.     mov    cx,g_size[si]
  176.     lds    si,g_address[si]
  177.     rep    movsb
  178.     popm    ds,si,cx
  179.  
  180.     les    di,g_address[si]    ; free old storage
  181.     call    free
  182.     popm    es,di,ax
  183.  
  184.     mov    wptr g_address[si],di    ; set new storage pointer and size
  185.     mov    wptr g_address[si+2],es
  186.     mov    g_size[si],ax
  187.     clc
  188.  
  189. gre1:    popm    es,ds,si,di
  190.     ret
  191. global_realloc endp
  192.  
  193.  
  194. ;;    global unlock
  195. ;
  196. ;    entry    BX    valid storage handle
  197. ;    note        flags do NOT change
  198. ;
  199. global_unlock proc
  200.     pushf
  201.     pushm    si,ds
  202.     call    read_global_entry
  203.     jc    gun1            ;  if bad handle
  204.     dec    g_lock[si]
  205. gun1:    popm    ds,si
  206.     popf
  207.     ret
  208. global_unlock endp
  209.  
  210.  
  211. ;;    read global entry
  212. ;
  213. ;    entry    BX    global handle
  214. ;    exit    DS:SI    global table for handle
  215. ;        Cf    if bad handle
  216. ;
  217. read_global_entry proc
  218.     pushm    ax,dx
  219.     mov    ax,@data
  220.     mov    ds,ax
  221.     lea    si,global_table
  222.  
  223.     cmp    bx,GLOBAL_MAX
  224.     ja    rge1            ;  if bad handle
  225.  
  226.     mov    ax,bx            ; multiply handle by structure size
  227.     dec    ax            ;  to select global table entry
  228.     mov    dx,size global_str
  229.     mul    dx
  230.     add    si,ax
  231. rge1:    popm    dx,ax
  232.     ret
  233. read_global_entry endp
  234.  
  235.     end
  236.