home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / RUKC10.ZIP / BORLAND.ZIP / MIDMEMBC.ASM < prev    next >
Assembly Source File  |  1993-03-06  |  12KB  |  236 lines

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