home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / PASCAL / OVERXMS / OVERXMS.ASM next >
Assembly Source File  |  1992-05-05  |  8KB  |  323 lines

  1. TITLE Turbo Pascal XMS support for loading overlays - By Wilbert van Leijen
  2. PAGE 65, 132
  3. LOCALS @@
  4.  
  5. Data       SEGMENT Word Public
  6.            ASSUME  DS:Data
  7.  
  8. ;  XMS block move record
  9.  
  10. XmsMoveType STRUC
  11.            BlkSize     DD    ?
  12.            SrcHandle   DW    ?
  13.            SrcOffset   DD    ?
  14.            DestHandle  DW    ?
  15.            DestOffset  DD    ?
  16. XmsMoveType ENDS
  17.  
  18. ;  TP overlay manager record
  19.  
  20. OvrHeader  STRUC
  21.            ReturnAddr  DD    ?         ; Virtual return address
  22.            FileOfs     DD    ?         ; Offset into overlay file
  23.            CodeSize    DW    ?         ; Size of overlay
  24.            FixupSize   DW    ?         ; Size of fixup table
  25.            EntryPts    DW    ?         ; Number of procedures
  26.            CodeListNext DW   ?         ; Segment of next overlay
  27.            LoadSeg     DW    ?         ; Start segment in memory
  28.            Reprieved   DW    ?         ; Loaded in memory flag
  29.            LoadListNext DW   ?         ; Segment of next in load list
  30.            XmsOffset   DD    ?         ; Offset into allocated XMS block
  31.            UserData    DW    3 DUP(?)
  32. OvrHeader  ENDS
  33.  
  34. XmsDriver  DD      ?                   ; Entry point of XMS driver
  35. ExitSave   DD      ?                   ; Pointer to previous exit proc
  36. XmsMove    XmsMoveType <>
  37. OvrXmsHandle DW    ?                   ; Returned by XMS driver
  38.  
  39.            Extrn   PrefixSeg : Word
  40.            Extrn   ExitProc : DWord
  41.            Extrn   OvrResult : Word
  42.            Extrn   OvrCodeList : Word
  43.            Extrn   OvrDosHandle : Word
  44.            Extrn   OvrHeapOrg : Word
  45.            Extrn   OvrReadBuf : DWord
  46. Data       ENDS
  47.  
  48. Code       SEGMENT Byte Public
  49.            ASSUME  CS:Code
  50.            Public  OvrInitXMS
  51.  
  52. ovrIOError     EQU     -4
  53. ovrNoXMSDriver EQU     -7
  54. ovrNoXMSMemory EQU     -8
  55.  
  56. OvrXmsExit PROC
  57.  
  58. ; Release handle and XMS memory
  59.  
  60.         MOV    DX, [OvrXmsHandle]
  61.         MOV    AH, 10
  62.         CALL   [XmsDriver]
  63.  
  64. ; Restore pointer to previous exit procedure
  65.  
  66.         LES    AX, [ExitSave]
  67.         MOV    Word Ptr [ExitProc], AX
  68.         MOV    Word Ptr [ExitProc+2], ES
  69.         RETF
  70. OvrXmsExit ENDP
  71.  
  72. AllocateXms PROC
  73.  
  74. ;  Determine the size of the XMS block to allocate:
  75. ;  Walk the CodeListNext chain
  76. ;  Store the total codesize in DX:AX
  77.  
  78.         XOR    AX, AX
  79.         XOR    DX, DX
  80.         MOV    BX, [OvrCodeList]
  81. @@1:    ADD    BX, [PrefixSeg]
  82.         ADD    BX, 10h
  83.         MOV    ES, BX
  84.         ADD    AX, ES:[OvrHeader.CodeSize]
  85.         ADC    DX, 0
  86.         MOV    BX, ES:[OvrHeader.CodeListNext]
  87.         OR     BX, BX
  88.         JNZ    @@1
  89.  
  90. ;  Obtain number of kilobytes to allocate
  91.  
  92.         MOV    BX, 1024
  93.         DIV    BX
  94.         XCHG   DX, AX
  95.         INC    DX
  96.  
  97. ;  Allocate the block
  98.  
  99.         MOV    AH, 9
  100.         CALL   [XmsDriver]
  101.         OR     AX, AX
  102.         JZ     @@2
  103.         MOV    [OvrXmsHandle], DX
  104. @@2:    RETN
  105. AllocateXms ENDP
  106.  
  107. ;  Function XmsReadFunc(OvrSeg : Word) : Integer; Far;
  108.  
  109. XmsReadFunc PROC
  110.  
  111. ;  Swap the code from XMS to the heap
  112.  
  113.         PUSH   BP
  114.         MOV    BP, SP
  115.         MOV    ES, [BP+6]
  116.         MOV    AX, ES:[OvrHeader.CodeSize]
  117.         MOV    Word Ptr [XmsMove.BlkSize], AX
  118.         XOR    AX, AX
  119.         MOV    Word Ptr [XmsMove.BlkSize+2], AX
  120.         MOV    AX, [OvrXmsHandle]
  121.         MOV    [XmsMove.SrcHandle], AX
  122.         MOV    AX, Word Ptr ES:[OvrHeader.XmsOffset]
  123.         MOV    Word Ptr [XmsMove.SrcOffset], AX
  124.         MOV    AX, Word Ptr ES:[OvrHeader.XmsOffset+2]
  125.         MOV    Word Ptr [XmsMove.SrcOffset+2], AX
  126.         XOR    AX, AX
  127.         MOV    [XmsMove.DestHandle], AX
  128.         MOV    Word Ptr [XmsMove.DestOffset], AX
  129.         MOV    AX, ES:[OvrHeader.LoadSeg]
  130.         MOV    Word Ptr [XmsMove.DestOffset+2], AX
  131.         MOV    AH, 11
  132.         LEA    SI, XmsMove
  133.         CALL   [XmsDriver]
  134.         OR     AX, AX
  135.         JZ     @@1
  136.         DEC    AX
  137.         JMP    @@2
  138.  
  139. @@1:    MOV    AX, ovrIOError
  140. @@2:    POP    BP
  141.         RETF   2
  142. XmsReadFunc ENDP
  143.  
  144. ;  Copy an overlaid unit from the heap to XMS
  145. ;  If successful, carry flag is cleared
  146. ;  In/Out:
  147. ;    BX:DI = offset into XMS memory block
  148.  
  149. CopyUnitToXms PROC
  150.  
  151. ;  XMS requires that an even number of bytes is moved
  152.  
  153.         MOV    DX, ES:[OvrHeader.CodeSize]
  154.         TEST   DX, 1
  155.         JZ     @@1
  156.         INC    DX
  157.         INC    ES:[OvrHeader.CodeSize]
  158.  
  159. ;  Get the fields of the XMS block move structure
  160.  
  161. @@1:    MOV    Word Ptr [XmsMove.BlkSize], DX
  162.         XOR    AX, AX
  163.         MOV    Word Ptr [XmsMove.BlkSize+2], AX
  164.         MOV    [XmsMove.SrcHandle], AX
  165.         MOV    Word Ptr [XmsMove.SrcOffset], AX
  166.         MOV    AX, [OvrHeapOrg]
  167.         MOV    Word Ptr [XmsMove.SrcOffset+2], AX
  168.         MOV    AX, [OvrXmsHandle]
  169.         MOV    [XmsMove.DestHandle], AX
  170.         MOV    Word Ptr [XmsMove.DestOffset], DI
  171.         MOV    Word Ptr [XmsMove.DestOffset+2], BX
  172.         MOV    AH, 11
  173.         LEA    SI, XmsMove
  174.         CALL   [XmsDriver]
  175.  
  176. ;  Bump code size
  177.  
  178.         ADD    DI, DX
  179.         ADC    BX, 0
  180.  
  181. ;  Check return code from XMS driver
  182.  
  183.         OR     AX, AX
  184.         JZ     @@2
  185.         CLC
  186.         RETN
  187.  
  188. @@2:    STC
  189.         RETN
  190. CopyUnitToXms ENDP
  191.  
  192. OvrXmsLoad PROC
  193.         PUSH   BP
  194.         MOV    BP, SP
  195.  
  196. ;  Walk the CodeList chain
  197. ;  First segment is PrefixSeg+10h+OvrCodeList
  198. ;  Push each element of overlaid unit list on the stack
  199. ;  Keep the size of the linked list in CX
  200.  
  201.         MOV    AX, [OvrCodeList]
  202.         XOR    CX, CX
  203. @@1:    ADD    AX, [PrefixSeg]
  204.         ADD    AX, 10h
  205.         MOV    ES, AX
  206.         PUSH   AX
  207.         INC    CX
  208.         MOV    AX, ES:[OvrHeader.CodeListNext]
  209.         OR     AX, AX
  210.         JNZ    @@1
  211.  
  212. ;  Loop:
  213. ;    Pop each element of the overlaid unit list from the stack
  214.  
  215.         XOR    BX, BX
  216.         XOR    DI, DI
  217. @@2:    POP    ES
  218.         PUSH   CX
  219.         MOV    AX, [OvrHeapOrg]
  220.         MOV    ES:[OvrHeader.LoadSeg], AX
  221.         MOV    Word Ptr ES:[OvrHeader.XmsOffset+2], BX
  222.         MOV    Word Ptr ES:[OvrHeader.XmsOffset], DI
  223.  
  224. ;  Load overlay from disk
  225.  
  226.         PUSH   BX
  227.         PUSH   DI
  228.         PUSH   ES
  229.         PUSH   ES
  230.         CALL   [OvrReadBuf]
  231.         POP    ES
  232.         POP    DI
  233.         POP    BX
  234.  
  235. ;  Flag unit as 'unloaded'; check return code
  236.  
  237.         MOV    ES:[OvrHeader.LoadSeg], 0
  238.         NEG    AX
  239.         JC     @@3
  240.  
  241.         CALL   CopyUnitToXms
  242.         JC     @@3
  243.  
  244.         POP    CX
  245.         LOOP   @@2
  246.  
  247. @@3:    MOV    SP, BP
  248.         POP    BP
  249.         RETN
  250. OvrXMSLoad ENDP
  251.  
  252. OvrInitXMS PROC
  253.  
  254. ;  Make sure the file's been opened
  255.  
  256.         XOR    AX, AX
  257.         CMP    AX, [OvrDOSHandle]
  258.         JNE    @@1
  259.         DEC    AX                      ; ovrError
  260.         JMP    @@5
  261.  
  262. ;  Check presence of XMS driver
  263.  
  264. @@1:    MOV    AX, 4300h
  265.         INT    2Fh
  266.         CMP    AL, 80h
  267.         JE     @@2
  268.         MOV    AX, ovrNoXmsDriver
  269.         JMP    @@5
  270.  
  271. ;  Get XMS driver's entry point
  272.  
  273. @@2:    MOV    AX, 4310h
  274.         INT    2Fh
  275.         MOV    Word Ptr [XmsDriver], BX
  276.         MOV    Word Ptr [XmsDriver+2], ES
  277.         CALL   AllocateXms
  278.         JNZ    @@3
  279.         MOV    AX, ovrNoXMSMemory
  280.         JMP    @@5
  281.  
  282. ;  Load the overlay into XMS
  283.  
  284. @@3:    CALL   OvrXmsLoad
  285.         JNC    @@4
  286.  
  287. ;  An error occurred.  Release handle and XMS memory
  288.  
  289.         MOV    DX, [OvrXmsHandle]
  290.         MOV    AH, 10
  291.         CALL   [XmsDriver]
  292.         MOV    AX, ovrIOError
  293.         JMP    @@5
  294.  
  295. ;  Close file
  296.  
  297. @@4:    MOV    BX, [OvrDOSHandle]
  298.         MOV    AH, 3Eh
  299.         INT    21h
  300.  
  301. ;  OvrReadBuf := XmsReadFunc
  302.  
  303.         MOV    Word Ptr [OvrReadBuf], Offset XmsReadFunc
  304.         MOV    Word Ptr [OvrReadBuf+2], CS
  305.  
  306. ;  ExitSave := ExitProc
  307. ;  ExitProc := OvrXmsExit
  308.  
  309.         LES    AX, [ExitProc]
  310.         MOV    Word Ptr [ExitSave], AX
  311.         MOV    Word Ptr [ExitSave+2], ES
  312.         MOV    Word Ptr [ExitProc], Offset OvrXmsExit
  313.         MOV    Word Ptr [ExitProc+2], CS
  314.  
  315. ;  Return result of initialisation
  316.  
  317.         XOR    AX, AX
  318. @@5:    MOV    [OvrResult], AX
  319.         RETF
  320. OvrInitXMS ENDP
  321.  
  322. Code       ENDS
  323.            END