home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / XLIB40.ZIP / EASYX.ASM < prev    next >
Assembly Source File  |  1994-03-23  |  14KB  |  339 lines

  1.                .MODEL         LARGE,PASCAL
  2.                .386P
  3.  
  4. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5. ;TASM Modifications
  6. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7.  
  8. ;TASM users should set TASMMODE below to TRUE.
  9.  
  10. TRUE           EQU            1
  11. FALSE          EQU            0
  12.  
  13. TASMMODE       =              FALSE
  14.  
  15.                IF TASMMODE
  16.                MASM51
  17.                QUIRKS
  18.                NOJUMPS
  19.  
  20. PUSHW          MACRO IMMEDIATE16:REST                       ;PUSH imm16 (for TASM compatibility)
  21.                IF (@WordSize EQ 4)
  22.                DB             66H
  23.                ENDIF
  24.                DB             68H
  25.                DW             IMMEDIATE16
  26.                ENDM
  27.  
  28. PUSHD          MACRO IMMEDIATE32:REST                       ;PUSH imm32 (for TASM compatibility)
  29.                IF (@WordSize EQ 2)
  30.                DB             66H
  31.                ENDIF
  32.                DB             68H
  33.                DD             IMMEDIATE32
  34.                ENDM
  35.  
  36.                INCLUDE        XLIBB.INC
  37.                ELSE
  38. ARG            TEXTEQU        <>
  39.                OPTION         PROC:PRIVATE
  40.                OPTION         NOLJMP
  41.                INCLUDE        XLIB.INC
  42.                ENDIF
  43.  
  44.  
  45. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  46. ;DSEG declaration.  The DSEG data segment has combine type 'FAR_DATA' when
  47. ;being used in a Borland library.  Under most memory models, Borland places all
  48. ;segments with combine type 'DATA' in DGROUP.  Unfortunately, the offsets seen
  49. ;by the library in such segments may have a different base than those seen by C.
  50. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  51.  
  52.                IF TASMMODE
  53. DSEG           SEGMENT PARA PUBLIC USE16 'FAR_DATA'
  54.                ELSE
  55. DSEG           SEGMENT PARA PUBLIC USE16 'DATA'
  56.                ENDIF
  57.                ASSUME DS:DSEG
  58.  
  59. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  60. ;Stacks used for MOVMEM routine.  Stacks are dynamically allocated to cover the
  61. ;possibility that MOVMEM is called both within the main thread of execution and
  62. ;in interrupt handlers.  The possibility of nested interrupts is also covered.
  63. ;Calls to MOVMEM may be nested four deep.  Each dynamically allocated stack
  64. ;contains 100H bytes.
  65. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  66.  
  67.                ALIGN          8
  68.                DB 800H DUP(0)                               ;Sufficient space for four stacks
  69. ISTKPTR        DD             OFFSET $                      ;Initial stack pointer (dynamically adjusted)
  70. STKALLOC       EQU            200H                          ;Number of bytes allocated per stack for MOVMEM
  71.  
  72. DSEG           ENDS
  73.  
  74. CSEG           SEGMENT PARA PUBLIC USE16 'CODE'
  75.                ASSUME CS:CSEG
  76.  
  77.                IF TASMMODE
  78.                SMALLSTACK
  79.                ENDIF
  80.  
  81. ;Allocate extended memory block.  Error code returned in DX:AX.  Arguments are:
  82. ;NOBYTES:DWORD = Number of bytes to allocate
  83. ;ADRPTR:DWORD = Far pointer to linear address of allocated block
  84. ;SIZEPTR:DWORD = Far pointer to size of allocated block
  85. ;HANDLEPTR:DWORD = Far pointer to handle of allocated block
  86. XMALLOC        PROC FAR,
  87.                ARG NOBYTES:DWORD,ADRPTR:DWORD,SIZEPTR:DWORD,HANDLEPTR:DWORD                         ;Number of bytes to allocate
  88.                PUSH           EBX
  89.                PUSH           ECX
  90.                PUSH           DS
  91.                MOV            EAX,NOBYTES
  92.                CALL           GETMEM
  93.                OR             EAX,EAX
  94.                JNZ            SHORT EXIT
  95.                PUSH           EBX
  96.                LDS            BX,ADRPTR
  97.                MOV            [BX],EDX
  98.                LDS            BX,SIZEPTR
  99.                MOV            [BX],ECX
  100.                LDS            BX,HANDLEPTR
  101.                POP            DWORD PTR [BX]
  102. EXIT:          PUSH           EAX                           ;Return error code in DX:AX
  103.                POP            AX
  104.                POP            DX
  105.                POP            DS
  106.                POP            ECX
  107.                POP            EBX
  108.                RET
  109. XMALLOC        ENDP
  110.  
  111. ;Release extended memory block.  Error code returned in DX:AX.  Arguments are:
  112. ;HANDLE:DWORD = Handle to previously allocated block
  113. XFREE          PROC FAR,
  114.                ARG HANDLE:DWORD                             ;Handle to previously allocated block
  115.                MOV            EAX,HANDLE
  116.                CALL           FREEMEM
  117.                PUSH           EAX                           ;Put error code in DX:AX
  118.                POP            AX
  119.                POP            DX
  120.                RET
  121. XFREE          ENDP
  122.  
  123. ;Map physical memory to logical address space.  Error code returned in DX:AX.
  124. ;Arguments are:
  125. ;PHYSADR:DWORD = Linear address of physical memory
  126. ;BLKSIZE:DWORD = Size of memory block (in bytes)
  127. ;LOGADRPTR:DWORD = Far pointer to DWORD to receive logical address
  128. MAPIOMEM       PROC FAR,
  129.                ARG PHYSADR:DWORD,BLKSIZE:DWORD,LOGADRPTR:DWORD
  130.                PUSH           BX
  131.                PUSH           DS
  132.                MOV            EDX,PHYSADR
  133.                MOV            EAX,BLKSIZE
  134.                PUSHD          OFFSET PMMAPIO
  135.                CALL           CALLPM
  136.                LDS            BX,LOGADRPTR
  137.                MOV            [BX],EDX
  138.                PUSH           EAX                           ;Place error code in DX:AX
  139.                POP            AX
  140.                POP            DX
  141.                POP            DS
  142.                POP            BX
  143.                RET
  144. MAPIOMEM       ENDP
  145.  
  146. ;Move memory.  This routine is suitable for interrupt handlers.  It uses a
  147. ;stack in DSEG rather than TSEG.  Arguments are:
  148. ;DESTADR:DWORD = Destination address.
  149. ;SOURCEADR:DWORD = Source address.
  150. ;NOBYTES:DWORD = Number of bytes to transfer.
  151.                ALIGN          16
  152. MOVMEM         PROC FAR,
  153.                ARG DESTADR:DWORD,SOURCEADR:DWORD,NOBYTES:DWORD
  154.                PUSHAD
  155.                PUSH           DS
  156.                PUSH           ES
  157.                PUSH           FS
  158.                PUSH           GS
  159.                MOV            AX,DSEG
  160.                MOV            DS,AX
  161.                MOV            ESI,SOURCEADR                 ;Load registers as required by MOVMEM32
  162.                MOV            EDI,DESTADR
  163.                MOV            ECX,NOBYTES
  164.                MOV            EDX,ISTKPTR                   ;Get currently available pointer for the dynamic stack
  165.                SUB            ISTKPTR,STKALLOC              ;Prepare dynamic stack for possibility of interrupt call back to this routine
  166.                MOV            BX,SP                         ;Save the old stack in EBX
  167.                PUSH           SS
  168.                PUSH           BX
  169.                POP            EBX
  170.                MOV            SS,AX                         ;Load the dynamic stack
  171.                MOV            ESP,EDX
  172.                CALL           SWITCHPM                      ;Switch to 16-bit protected mode
  173.                PUSHW          0H                            ;PUSH 32-bit far return address back to this procedure
  174.                MOV            AX,CSEGSEL
  175.                PUSH           AX
  176.                PUSHD          OFFSET RETADR
  177.                PUSHW          0H                            ;PUSH 32-bit far address of MOVMEM32
  178.                MOV            AX,TSEGSEL
  179.                PUSH           AX
  180.                PUSHD          OFFSET MOVMEM32
  181.                MOV            DS,FLATDSEL                   ;Switch to flat data model
  182.                DB             66H                           ;Execute 32-bit RETF
  183.                RETF
  184. RETADR:        CALL           SWITCHRM                      ;Switch back to real mode
  185.                PUSH           EBX                           ;Load calling stack
  186.                LSS            SP,[ESP]
  187.                ADD            ISTKPTR,STKALLOC              ;Adjust dynamic stack pointer
  188.                POP            GS
  189.                POP            FS
  190.                POP            ES
  191.                POP            DS
  192.                POPAD
  193.                RET
  194. MOVMEM         ENDP
  195.  
  196. ;Calculate linear address from segment address.  Call with segment address on
  197. ;stack.  Linear address returned in DX:AX.
  198. LINADR         PROC FAR,
  199.                ARG SEGADDRESS:DWORD                         ;Segment address of variable
  200.                MOV            AX,WORD PTR SEGADDRESS[2]     ;Do not corrupt high words (might be used in 16-bit interrupt handler)
  201.                XOR            DX,DX
  202.                SHLD           DX,AX,4
  203.                SHL            AX,4
  204.                ADD            AX,WORD PTR SEGADDRESS[0]
  205.                ADC            DX,0
  206.                RET
  207. LINADR         ENDP
  208.  
  209. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  210. ;Interfaces to XLIB file management routines.  Each of these procedures should
  211. ;be called with the segment address of the control block on the stack.  These
  212. ;routines cannot be called during interrupts since each routine calls DOS.
  213. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  214.  
  215. ;Create file.
  216. XFCREATE       PROC FAR
  217.                PUSHD          OFFSET PMXCREATE
  218.                JMP            CHAINTOPM
  219. XFCREATE       ENDP
  220.  
  221. ;Open file.
  222. XFOPEN         PROC FAR
  223.                PUSHD          OFFSET PMXOPEN
  224.                JMP            CHAINTOPM
  225. XFOPEN         ENDP
  226.  
  227. ;Close file.
  228. XFCLOSE        PROC FAR
  229.                PUSHD          OFFSET PMXCLOSE
  230.                JMP            CHAINTOPM
  231. XFCLOSE        ENDP
  232.  
  233. ;Load file
  234. XFLOAD         PROC FAR
  235.                PUSHD          OFFSET PMXLOAD
  236.                JMP            CHAINTOPM
  237. XFLOAD         ENDP
  238.  
  239. ;Save file.
  240. XFSAVE         PROC FAR
  241.                PUSHD          OFFSET PMXSAVE
  242.                JMP            CHAINTOPM
  243. XFSAVE         ENDP
  244.  
  245. ;Random read file.
  246. XFREAD         PROC FAR
  247.                PUSHD          OFFSET PMXREAD
  248.                JMP            CHAINTOPM
  249. XFREAD         ENDP
  250.  
  251. ;Random write file.
  252. XFWRITE        PROC FAR
  253.                PUSHD          OFFSET PMXWRITE
  254.                JMP            CHAINTOPM
  255. XFWRITE        ENDP
  256.  
  257. ;Transfer control to protected mode after converting segment address of control
  258. ;block to linear address in EAX.
  259. CHAINTOPM      PROC FAR
  260.                PUSH           DWORD PTR [ESP+8]             ;PUSH segment address of control block
  261.                CALL           LINADR
  262.                PUSH           DX
  263.                PUSH           AX
  264.                POP            EAX
  265.                CALL           CALLPM
  266.                RET            4
  267. CHAINTOPM      ENDP
  268.  
  269.                PUBLIC PASCAL XMALLOC
  270.                PUBLIC PASCAL XFREE
  271.                PUBLIC PASCAL MAPIOMEM
  272.                PUBLIC PASCAL LINADR
  273.                PUBLIC PASCAL MOVMEM
  274.                PUBLIC PASCAL XFCREATE
  275.                PUBLIC PASCAL XFOPEN
  276.                PUBLIC PASCAL XFCLOSE
  277.                PUBLIC PASCAL XFLOAD
  278.                PUBLIC PASCAL XFSAVE
  279.                PUBLIC PASCAL XFREAD
  280.                PUBLIC PASCAL XFWRITE
  281.  
  282. CSEG           ENDS
  283.  
  284. TSEG           SEGMENT PARA PUBLIC USE32 'CODE'
  285.                ASSUME CS:TSEG
  286.  
  287.                IF TASMMODE
  288.                LARGESTACK
  289.                ENDIF
  290.  
  291. ;Transfer memory.  Call with source address in ESI, destination address in EDI,
  292. ;and number of bytes to transfer in ECX.  Does not preserve registers.  This
  293. ;routine is far and is therefore a departure from XLIB policy.  This approach
  294. ;is used because the routine is not entered with the standard XLIB mode switch
  295. ;procedures, CALLPM and ENTERPM.  Standard mode switch procedures are not used
  296. ;because they are not reentrant and therefore cannot be used in interrupt
  297. ;handlers.
  298.                ALIGN          16
  299. MOVMEM32       PROC FAR
  300.                CMP            EDI,ESI
  301.                JBE            ENTERDN4
  302.                JMP            ENTERUP4
  303.                ALIGN          4
  304. UP4LOOP:       MOV            EAX,[ESI+1*ECX]               ;Destination address is higher than source address
  305.                MOV            [EDI+1*ECX],EAX
  306. ENTERUP4:      SUB            ECX,4
  307.                JAE            UP4LOOP
  308.                ADD            ECX,4
  309.                JNZ            ENTERUP1
  310.                RET
  311.                ALIGN          4
  312. UP1LOOP:       MOV            AL,[ESI+1*ECX]
  313.                MOV            [EDI+1*ECX],AL
  314. ENTERUP1:      DEC            ECX
  315.                JNS            UP1LOOP
  316.                RET
  317.                ALIGN          4
  318. DN4LOOP:       MOV            EAX,[ESI]                     ;Destination address is lower than source address
  319.                MOV            [EDI],EAX
  320.                ADD            ESI,4
  321.                ADD            EDI,4
  322. ENTERDN4:      SUB            ECX,4
  323.                JAE            DN4LOOP
  324.                ADD            ECX,4
  325.                JNZ            ENTERDN1
  326.                RET
  327.                ALIGN          4
  328. DN1LOOP:       MOV            AL,[ESI]
  329.                MOV            [EDI],AL
  330.                INC            ESI
  331.                INC            EDI
  332. ENTERDN1:      DEC            ECX
  333.                JNS            DN1LOOP
  334.                RET
  335. MOVMEM32       ENDP
  336.  
  337. TSEG           ENDS
  338.                END
  339.