home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / caway349.zip / BIN / MULTNEAR.ASM < prev    next >
Assembly Source File  |  1996-06-17  |  7KB  |  285 lines

  1. ;
  2. ;A demo of using multiple 16/32-bit segments and near model
  3. ;This example will NOT work with FLAT model 
  4. ;
  5.  
  6.     .386            ;This order of .386 and .model
  7.     .model small        ;ensures use32 segments.
  8.     .stack 1024        ;should be enough for most.
  9.  
  10.     include cw.inc        ;define CauseWay API
  11.  
  12. ;
  13. ;If you set both ProgramLocking and DynamicLocking to be nonzero, the effect
  14. ;will be to make sure only physical memory is used to run the program and any
  15. ;of its MALLOC allocations. Use these options for time critical applications.
  16. ;
  17.  
  18. ;
  19. ;For programs that need their memory locking set ProgramLocking to be nonzero.
  20. ;That will make sure all of the program's memory is locked during the startup
  21. ;code. If the lock fails then it indicates not enough physical memory present.
  22. ;
  23. ProgramLocking    equ    1
  24.  
  25.  
  26. ;
  27. ;For programs that need / want all of their dynamicly allocated memory to be
  28. ;locked to prevent paging delays, set DynamicLocking to be nonzero. If a
  29. ;memory block allocated cannot be locked it will be treated as if there were
  30. ;not enough logical memory available.
  31. ;
  32. DynamicLocking    equ    1
  33.  
  34.     .code
  35.  
  36. ;-------------------------------------------------------------------------------
  37. start    proc    near
  38.     mov    ax,DGROUP        ;Make our data addressable
  39.     mov    ds,ax        ;ready for error messages.
  40.     ;
  41.     if    ProgramLocking
  42. ;
  43. ;This code assumes CS (_TEXT) is the first segment and _STACK (SS) is the last.
  44. ;It works out the start and end addresses of the program and attempts to lock
  45. ;that region of memory.
  46. ;This approach does NOT work with FLAT model (use ESP instead).
  47. ;
  48.     mov    bx,cs
  49.     sys    GetSelDet32        ;Get linear address of the start
  50.     mov    esi,edx        ;of the program.
  51.     mov    bx,ss
  52.     sys    GetSelDet32        ;Get linear address of the stack.
  53.     add    ecx,edx
  54.     inc    ecx        ;address+limit+1=end address.
  55.     sub    ecx,esi        ;calculate program length.
  56.     sys    LockMem32
  57.     jc    memory_error        ;not enough physical memory.
  58.     endif
  59. ;
  60. ;To be able to access any address as DGROUP we need to modify the DGROUP (DS)
  61. ;selector to give it a limit of 4G-1 (limit=length-1). This removes segment
  62. ;limit protection for stray memory access but in most cases these will be
  63. ;picked up by the paging protection mechanism due to physical memory not being
  64. ;mapped in.
  65. ;
  66.     mov    bx,ds
  67.     sys    GetSelDet32        ;Get DGROUP details.
  68.     jc    selector_error
  69.     mov    ecx,-1        ;Need limit of -1 for DS relative
  70.     sys    SetSelDet32        ;addressing of everything.
  71.     jc    selector_error
  72. ;
  73. ;To complete the DGROUP relative addressing scheme we need to adjust ESP and
  74. ;load SS with DGROUP so that ESP/EBP/SS memory referances will be DGROUP
  75. ;relative as well.
  76. ;
  77.     mov    esi,edx        ;EDX is already DGROUP address.
  78.     mov    bx,ss
  79.     sys    GetSelDet32        ;Get linear address of the stack.
  80.     jc    selector_error
  81.     sub    edx,esi        ;calculate distance between
  82.     mov    ax,ds        ;SS and DGROUP.
  83.     mov    ss,ax        ;Do SS=DS and adjust ESP to make
  84.     add    esp,edx        ;the stack DS relative.
  85. ;
  86. ;Calculate DGROUP relative address of the PSP.
  87. ;
  88.     mov    bx,es        ;ES is the PSP selector.
  89.     sys    GetSelDet32
  90.     jc    selector_error
  91.     mov    esi,edx
  92.     call    Linear2DGROUP    ;Conver linear to DGROUP
  93.     mov    PSP_Pointer,esi
  94. ;
  95. ;Calculate DGROUP relative address of the environment variables.
  96. ;
  97.     mov    bx,es:[2ch]
  98.     sys    GetSelDet32
  99.     jc    selector_error
  100.     mov    esi,edx
  101.     call    Linear2DGROUP
  102.     mov    ENV_Pointer,esi
  103. ;
  104. ;Setup the other segment registers to finish things off.
  105. ;
  106.     mov    ax,ds
  107.     mov    es,ax
  108.     mov    fs,ax
  109.     mov    gs,ax
  110.  
  111. ;
  112. ;From this point on (except hardware interrupt handlers) DS=ES=FS=GS=SS=DGROUP
  113. ;and memory allocated via MALLOC can be addressed without thinking about segment
  114. ;registers. Insert your code here.
  115. ;
  116.  
  117.     mov    esi,0b8000h        ;Linear address of text screen.
  118.     call    Linear2DGROUP
  119.     mov    edi,esi        ;simple demo of using DGROUP
  120.     mov    ecx,(80*25)/2    ;relative addressing to get
  121.     mov    eax,24422442h    ;at any memory address.
  122.     rep    stosd
  123.  
  124.     jmp    exit
  125.  
  126. ;
  127. ;Not enough memory for this program.
  128. ;
  129. memory_error:    mov    edx,offset memory_message
  130.     jmp    error_print
  131.  
  132. ;
  133. ;A most unlikely error. The selectors that can cause the program to come here
  134. ;are supplied by the extender so there shouldn't be any problems.
  135. ;
  136. selector_error: mov    edx,offset selector_message
  137.  
  138. ;
  139. ;Print the message pointed to by EDX.
  140. ;
  141. error_print:    mov    ah,9
  142.     int    21h
  143.  
  144. ;
  145. ;Go back to CauseWay, which will wind up back in DOS.
  146. ;
  147. exit:    mov    ax,4c00h
  148.     int    21h
  149. start    endp
  150.  
  151.  
  152. ;-------------------------------------------------------------------------------
  153. ;
  154. ;Allocate some DGROUP relative memory.
  155. ;
  156. ;On Entry:
  157. ;
  158. ;ECX    - Bytes needed.
  159. ;
  160. ;On Exit:
  161. ;
  162. ;Carry set on error else,
  163. ;
  164. ;ESI    - DGROUP relative address of meemory.
  165. ;
  166. malloc    proc    near
  167.     push    eax
  168.     push    ecx
  169.     if    DynamicLocking
  170.     add    ecx,4        ;make space for length storage.
  171.     endif
  172.     sys    GetMemLinear32    ;try to allocate the memory.
  173.     jc    malloc_2
  174.     if    DynamicLocking
  175.     sys    LockMem32        ;try to lock the memory.
  176.     jnc    malloc_1
  177.     sys    RelMemLinear32    ;better release the memory first.
  178.     stc
  179.     jmp    malloc_2
  180.     endif
  181. malloc_1:    call    Linear2DGROUP    ;make it DGROUP relative.
  182.     if    DynamicLocking
  183.     mov    [esi],ecx        ;store the block length ready
  184.     add    esi,4        ;for FREE to unlock it again.
  185.     endif
  186.     clc            ;make sure we return success.
  187. malloc_2:    pop    ecx
  188.     pop    eax
  189.     ret
  190. malloc    endp
  191.  
  192.  
  193. ;-------------------------------------------------------------------------------
  194. ;
  195. ;Release some memory allocated via MALLOC.
  196. ;
  197. ;On Entry:
  198. ;
  199. ;ESI    - DGROUP relative address of block to release.
  200. ;
  201. free    proc    near
  202.     push    eax
  203.     push    esi
  204.     if    DynamicLocking
  205.     push    ecx
  206.     sub    esi,4        ;move back to the block size
  207.     mov    ecx,[esi]        ;and retrieve it.
  208.     endif
  209.     call    DGROUP2Linear    ;convert address back to linear.
  210.     if    DynamicLocking
  211.     sys    UnLockMem32        ;unlock the memory again.
  212.     pop    ecx
  213.     endif
  214.     sys    RelMemLinear32    ;release the memory.
  215.     pop    esi
  216.     pop    eax
  217.     ret
  218. free    endp
  219.  
  220.  
  221. ;-------------------------------------------------------------------------------
  222. ;
  223. ;Convert linear address to DGROUP relative address.
  224. ;
  225. ;On Entry:
  226. ;
  227. ;ESI    - Linear address.
  228. ;
  229. ;On Exit:
  230. ;
  231. ;ESI    - DGROUP relative address.
  232. ;
  233. Linear2DGROUP    proc    near
  234.     push    eax
  235.     push    ebx
  236.     push    ecx
  237.     push    edx
  238.     mov    bx,ds
  239.     sys    GetSelDet32
  240.     sub    esi,edx
  241.     pop    edx
  242.     pop    ecx
  243.     pop    ebx
  244.     pop    eax
  245.     ret
  246. Linear2DGROUP    endp
  247.  
  248.  
  249. ;-------------------------------------------------------------------------------
  250. ;
  251. ;Convert DGROUP relative address to a linear address.
  252. ;
  253. ;On Entry:
  254. ;
  255. ;ESI    - DGROUP relative address.
  256. ;
  257. ;On Exit:
  258. ;
  259. ;ESI    - Linear address.
  260. ;
  261. DGROUP2Linear    proc    near
  262.     push    eax
  263.     push    ebx
  264.     push    ecx
  265.     push    edx
  266.     mov    bx,ds
  267.     sys    GetSelDet32
  268.     add    esi,edx
  269.     pop    edx
  270.     pop    ecx
  271.     pop    ebx
  272.     pop    eax
  273.     ret
  274. DGROUP2Linear    endp
  275.  
  276.     .data
  277.  
  278. PSP_Pointer    dd ?
  279. ENV_Pointer    dd ?
  280.  
  281. memory_message    db "Not enough memory.",13,10,"$"
  282. selector_message db "Selector error, system must be corrupt.",13,10,"$"
  283.  
  284.     end start
  285.