home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / RUKC1D.ZIP / BORLAND.ZIP / DACMEMBC.ASM next >
Assembly Source File  |  1994-02-27  |  13KB  |  239 lines

  1. PAGE 81,132
  2. ;dac$malloc
  3. ;dac$free
  4. ;-----------------------------------------------------------------------|
  5. ;    ScanSoft          (C)1993 Cornel H Huth     ALL RIGHTS RESERVED    |
  6. ;-----------------------------------------------------------------------|
  7. ;     date:      27-Feb-94                                              |
  8. ; function:      Memory routines for C compilers                        |
  9. ;                that do not allow DOS allocations to be mixed with     |
  10. ;                _malloc allocations (including _calloc, etc.)          |
  11. ;    notes:      This malady afflicts Borland C compilers               |
  12. ;                All registers saved since there's no telling what      |
  13. ;                registers the runtime code uses                        |
  14. ;                                                                       |
  15. ;                                                                       |
  16. ;The code below will work in either LARGE or HUGE memory modules.       |
  17. ;It will not, as written, work in the medium model. With minor changes, |
  18. ;the medium model could be supported. Not needed, however, in the       |
  19. ;medium model.                                                          |
  20. ;                                                                       |
  21. ;This code was written with MASM 5.10A in mind though TASM should       |
  22. ;handle it, too.                                                        |
  23. ;                                                                       |
  24. ;To assemble:                                                           |
  25. ;                                                                       |
  26. ;       C>masm dacmembc /mx; (/mx=preserve case on globals)             |
  27. ;                                                                       |
  28. ;Then do the following:                                                 |
  29. ;                                                                       |
  30. ; Replace DACMEM.OBJ in RUCKDAC.LIB:                                    |
  31. ;                                                                       |
  32. ;        C>lib RUCKDAC -dacmem +dacmembc;                               |
  33. ;  -or-                                                                 |
  34. ;        C>tlib RUCKDAC -dacmem +dacmembc                               |
  35. ;        (requires TLIB.EXE version 3.00 or earlier)                    |
  36. ;                                                                       |
  37. ;Before doing anything, read the BORLAND.FIX text file. It documents    |
  38. ;what and how to make a Borland-workable RUCKDAC.LIB.                   |
  39. ;                                                                       |
  40. ;Note: This replacement module does not enable DOS-controlled UMBs as   |
  41. ;      the normal dac$malloc does. A safety call since I don't know how |
  42. ;      Borland's memory manager would deal with it.                     |
  43. ;                                                                       |
  44. ;Important: Unlike allocation through DOS (INT48), _malloc and _free    |
  45. ;           require DS->DGROUP                                          |
  46. ;-----------------------------------------------------------------------|
  47. WPTR EQU <WORD PTR>
  48.  
  49.                 .MODEL LARGE,PASCAL
  50.  
  51.                 .CODE
  52.  
  53. EXTRN _malloc:FAR
  54. EXTRN _free:FAR
  55.  
  56.                 ;MAXTRACKER is the number of allocations that can be open at
  57.                 ;any one time. Consider each open file to require one Track.
  58.                 ;A good MAXTRACKER value would be the total number of files you
  59.                 ;require to be open at one time plus 5. Each MAXTRACKER
  60.                 ;requires 6 bytes of code space. Unless you're starving for
  61.                 ;RAM, MAXTRACKER is fine at 254 (uses about 1.5K of code space.)
  62.                 ;A mod file load can use up to 40 or so allocations!
  63.  
  64. MAXTRACKER EQU 254
  65.  
  66.                 ;TrackerFP stores far pointers as returned by _malloc
  67.                 ;so that _free can be used (_free requires exact FP match)
  68. EVEN
  69. TrackerFP       dd MAXTRACKER DUP (0)   ;32-bit segmented pointer of _malloc
  70.                 dd 0                    ;and required by _free
  71.  
  72.                 ;TrackerSeg stores the 16-bit segment pointer converted from
  73.                 ;the far pointer returned by _malloc. See dac$malloc for how
  74.                 ;this is done. This is used as a lookup value in dac$free.
  75.  
  76. TrackerSeg      dw MAXTRACKER DUP (0)   ;thunk it to a 16-bit segment pointer
  77.                 dw -1
  78.  
  79. ;-----------------------------------------------------------------------|
  80. ;     date:      31-Jan-93                                              |
  81. ; function:      allocate memory                                        |
  82. ;   caller:      FAR, ASSEMBLY                                          |
  83. ;    stack:      n/a                                                    |
  84. ;       in:      bx=paragraphs to allocate                              |
  85. ;      out:      NC=ax=seg                                              |
  86. ;                CY=ax=8=not enough memory                              |
  87. ;     uses:      ax (return)                                            |
  88. ;    notes:      call with bx=FFFF and bx returns w/ largest block free |
  89. ;                (according to DOS)                                     |
  90. ;                                                                       |
  91. ;06-Mar-93-chh                                                          |
  92. ;-Need to preserve bx if making allocation since bx used as size to     |
  93. ; on return.                                                            |
  94. ;-For Huge Model mode need to first push element size, the long count...|
  95. ; ...Large model just ignores the first two pushes. MS C7 anyway.       |
  96. ;-Added DS reload                                                       |
  97. ;                                                                       |
  98. ;-----------------------------------------------------------------------|
  99. dac$malloc      PROC USES cx dx si di es ds
  100.  
  101.                 cmp     bx,-1           ;just asking for available memory?
  102.                 jne     dac$malloc01    ;no
  103.                 mov ah,48h              ;yes, regular DOS check should do
  104.                 int 21h                 ;though RUCKDAC never makes a memory
  105.                 jmp     SHORT dac$mallocXit ;inquiry...currently
  106.  
  107. dac$malloc01:   mov     cx,MAXTRACKER   ;scan for next free descriptor
  108.                 sub     ax,ax           ;0 indicates available
  109.                 push    cs
  110.                 mov     di,OFFSET TrackerSeg
  111.                 pop     es              ;es:di->TrackSeg start
  112.                 repne scasw
  113.                 jne     dac$mallocEx    ;none available
  114.                 mov     ax,di
  115.                 sub     ax,OFFSET TrackerSeg+2 ;ax=available slot (word)
  116.  
  117.                 push    bx              ;RUCKUS needs this later
  118.                 push    ax              ;save slot
  119.  
  120.                 sub     ax,ax
  121.                 inc     ax              ;(1) in case of huge model
  122.                 push    ax              ;put size on stack (char)
  123.                 dec     ax              ;(0) and high-word of elements
  124.                 push    ax              ;on stack (always 0 for RUCKUS)
  125.  
  126.                 mov     ax,bx           ;paras requested
  127.                 inc     ax              ;bump para request so we can norm it
  128.                 shl     ax,1            ;(thunk it would be more like it)
  129.                 shl     ax,1
  130.                 shl     ax,1
  131.                 shl     ax,1            ;paras to bytes
  132.                 push    ax              ;low-word of request
  133.  
  134.                 mov     ax,SEG DGROUP
  135.                 mov     ds,ax           ;_malloc runtime needs it
  136.  
  137.                 call    _malloc         ;appease the Borland Gods
  138.                 add     sp,6            ;here dx:ax is far pointer to block
  139.  
  140.                 pop     di              ;get back slot
  141.  
  142.                 mov     bx,dx           ;check for null pointer return
  143.                 or      bx,ax           ;allocation okay?
  144.  
  145.                 pop     bx              ;get size in paras back now
  146.                 jz      dac$mallocEx    ;no
  147.  
  148.                 mov     si,di           ;word slot index for TrackerSeg
  149.                 shl     di,1            ;dword slot index for TrackerFP
  150.                 mov     WPTR cs:[TrackerFP+di],ax
  151.                 mov     WPTR cs:[TrackerFP+di+2],dx
  152.  
  153.                 ;normalize the 32-bit pointer to a 16-bit segment pointer
  154.                 ;we can do this because we requested 1 additional paragraph
  155.                 ;so that we can just drop the normalized offset and start
  156.                 ;using the allocated memory block at the next paragraph
  157.  
  158.                 ;;since we won't be using the fractional-para offset of the
  159.                 ;;norm'ed far pointer we can skip the overhead
  160.  
  161.                 ;;mov     bx,ax           ;save full offset
  162.                 ;;and     ax,000Fh        ;non-paragraph portion
  163.                 ;;mov     cx,ax           ;ax is normalized offset
  164.                 ;;mov     ax,bx           ;get full offset back
  165.  
  166.                 shr     ax,1            ;convert offset to full paras
  167.                 shr     ax,1
  168.                 shr     ax,1
  169.                 shr     ax,1
  170.                 add     ax,dx           ;add segment in
  171.                 inc     ax              ;bump to next paragraph
  172.                 mov     cs:[TrackerSeg+si],ax
  173.                 clc                     ;return 16-bit segment pointer in ax
  174. dac$mallocXit:  ret                     ;that RUCKDAC will use
  175.  
  176. dac$mallocEx:   mov     ax,8
  177.                 stc
  178.                 jmp     SHORT dac$mallocXit
  179.  
  180. dac$malloc      ENDP
  181.  
  182. ;-----------------------------------------------------------------------|
  183. ;     date:      31-Jan-93                                              |
  184. ; function:      free allocated memory                                  |
  185. ;   caller:      FAR, ASSEMBLY                                          |
  186. ;    stack:      n/a                                                    |
  187. ;       in:      es=segment pointer of block to free                    |
  188. ;      out:      NC=okay (at least this code, _free has not return code)|
  189. ;                CY=ax=9 invalid block (segment not in descriptor list  |
  190. ;     uses:      ax (return)                                            |
  191. ;    notes:      see dac$malloc above for more info                     |
  192. ;06-Mar-93-chh                                                          |
  193. ;-Added save of dword slot (di) before call to _free                    |
  194. ;-Added DS reload                                                       |
  195. ;-----------------------------------------------------------------------|
  196. dac$free        PROC USES bx cx dx si di ds es
  197.  
  198.                 mov     cx,MAXTRACKER   ;scan for matching descriptor
  199.                 mov     ax,es           ;search for this segment pointer
  200.                 push    cs
  201.                 mov     di,OFFSET TrackerSeg
  202.                 pop     es              ;es:di->TrackerSeg start
  203.                 repne scasw
  204.                 jne     dac$freeEx      ;not found, must be invalid block
  205.  
  206.                 sub     ax,ax
  207.                 sub     di,OFFSET TrackerSeg+2  ;di=matched slot (word)
  208.  
  209.                 push    di                      ;save word slot
  210.                 shl     di,1                    ;dword slot index
  211.                 push    di                      ;save dword slot
  212.  
  213.                 push    WPTR cs:[TrackerFP+di+2];segment to block to release
  214.                 push    WPTR cs:[TrackerFP+di]  ;offset
  215.  
  216.                 mov     ax,SEG DGROUP
  217.                 mov     ds,ax                   ;_free runtime needs it
  218.  
  219.                 call    _free                   ;appease them some more
  220.                 add     sp,4
  221.  
  222.                 sub     ax,ax
  223.                 pop     di                              ;get dword slot
  224.                 mov     WPTR cs:[TrackerFP+di+2],ax     ;clear descriptor info
  225.                 mov     WPTR cs:[TrackerFP+di],ax
  226.  
  227.                 pop     di                              ;get word slot index
  228.                 mov     cs:[TrackerSeg+di],ax           ;make slot available
  229. dac$freeXit:    ret
  230.  
  231. dac$freeEx:     mov     ax,9
  232.                 stc
  233.                 jmp     dac$freeXit
  234. dac$free        ENDP
  235.  
  236.                 END
  237.  
  238.  
  239.