home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Masterblend / cdsharewaremasterblend.iso / utils / mem-expa / xm286.asm < prev    next >
Assembly Source File  |  1989-03-21  |  13KB  |  528 lines

  1. ;**************************************************************************
  2. ;*    * * * 286 LOADALL information * * *
  3. ;**************************************************************************
  4.  
  5. ;*    * Segment Descriptor Access Bytes
  6. DEF_ACCESS    EQU    92H
  7.  
  8. DEF_LIMIT    EQU    0FFFFH
  9.  
  10. SEGREG_DESCRIPTOR STRUC
  11. SEG_BASE_LO    DW    0
  12. SEG_BASE_HI    DB    0
  13. SEG_ACCESS    DB    DEF_ACCESS
  14. SEG_LIMIT    DW    DEF_LIMIT
  15. SEGREG_DESCRIPTOR ENDS
  16.  
  17. DTR_DESCRIPTOR STRUC
  18. DTR_BASE    DW    ?
  19.         DB    ?
  20.         DB    0
  21. DTR_LIMIT    DW    ?
  22. DTR_DESCRIPTOR ENDS
  23.  
  24. LODAL286    MACRO    
  25.     DW    050Fh
  26. ENDM
  27.  
  28. ;*******************************************************************************
  29. ;
  30. ; MoveExtended286
  31. ;    XMM Move Extended Memory Block for the 80286
  32. ;
  33. ;    Copyright (c) 1988, Microsoft Corporation
  34. ;
  35. ; Entry:
  36. ;    ES:BX    Points to a MoveExtendedStruc
  37. ;
  38. ; Return:
  39. ;    AX = 1    Success
  40. ;    AX = 0    Failure
  41. ;        Error Code in BL
  42. ;
  43. ; Registers Destroyed:
  44. ;    Flags, CX, SI, DI, ES
  45. ;
  46. ;            WARNING
  47. ;            =======
  48. ;
  49. ; This routine enables interrupts and can be re-entered
  50. ;
  51. ; Notes:
  52. ;    The case of copying from conventional to conventional memory
  53. ;    is not treated specially in this example.
  54. ;
  55. ; History:
  56. ;    Wed Jul 13 - AWG - Original version
  57. ;-------------------------------------------------------------------------------
  58. ifndef    XM286INCLUDED
  59. public    MoveExtended286
  60. endif
  61. MoveExtended286 proc    near
  62.  
  63. assume    cs:code, ds:code, es:nothing
  64.  
  65.     sti                    ; Be nice
  66.     push    bp                ; Set up stack frame so we
  67.     mov    bp, sp                ; can have local variables
  68.     sub    sp, 18                ; Space for local variables
  69. Count      = -4                    ; Local DWORD for byte count
  70. MEReturn  = -6                    ; Local WORD for return code
  71. SrcHandle = -8
  72. DstHandle = -10
  73. SrcLinear = -14
  74. DstLinear = -18
  75.     push    bx
  76.     push    dx
  77.  
  78.     xor    ax, ax
  79.     mov    [bp.MEReturn], ax            ; Assume success
  80.     mov    [bp.SrcHandle], ax
  81.     mov    [bp.DstHandle], ax
  82.     mov    ax, word ptr es:[si.bCount]    ; Pick up length specified
  83.     mov    word ptr [bp.Count], ax
  84.     mov    cx, word ptr es:[si.bCount+2]
  85.     mov    word ptr [bp.Count+2], cx
  86.     or    cx, ax
  87.     jcxz    MEM2_Exit            ; Exit immediately if zero
  88.  
  89.     lea    bx, [si.SourceHandle]        ; Normalize Source
  90.     call    GetLinear286            ; Linear address in DX:AX
  91.     jc    short MEM2_SrcError              ; Have Dest Error Code
  92.     mov    word ptr [bp.SrcLinear], ax    ; Save Linear address
  93.     mov    word ptr [bp.SrcLinear+2], dx
  94.     mov    [bp.SrcHandle], bx        ; Save Handle for Unlock
  95.  
  96.     lea    bx, [si.DestHandle]        ; Normalize Destination
  97.     call    GetLinear286
  98.     jc    short MEM2_Error
  99.     mov    word ptr [bp.DstLinear], ax    ; Save Linear address
  100.     mov    word ptr [bp.DstLinear+2], dx
  101.     mov    [bp.DstHandle], bx        ; Save Handle for Unlock
  102.  
  103.     shr    word ptr [bp.Count+2], 1    ; Make word count
  104.     rcr    word ptr [bp.Count], 1
  105.     jc    short MEM2_InvCount              ; Odd count not allowed
  106.  
  107.     call    LocalEnableA20            ; Enable A20 for LoadAll code
  108.     cmp    ax, 1
  109.     jne    short MEM2_Error
  110.  
  111.     call    DoLoadAll
  112.  
  113.     call    LocalDisableA20
  114.     cmp    ax, 1
  115.     jne    short MEM2_Error
  116.  
  117. MEM2_Exit:
  118.     mov    bx, [bp.SrcHandle]        ; Unlock Handles if necessary
  119.     or    bx, bx
  120.     jz    short NoSrcHandle
  121.     dec    [bx.cLock]            ; Unlock Source
  122. NoSrcHandle:
  123.     mov    bx, [bp.DstHandle]
  124.     or    bx, bx
  125.     jz    short NoDstHandle
  126.     dec    [bx.cLock]            ; Unlock Destination
  127. NoDstHandle:
  128.     pop    dx
  129.     pop    bx
  130.     mov    ax, 1
  131.     cmp    word ptr [bp.MEReturn], 0
  132.     jz    short MEM2_Success
  133.     dec    ax
  134.     mov    bl, byte ptr [bp.MEReturn]
  135. MEM2_Success:
  136.     mov    sp, bp                ; Unwind stack
  137.     pop    bp
  138.     ret
  139.  
  140. MEM2_SrcError:
  141.     cmp    bl, ERR_LENINVALID        ; Invalid count
  142.     je    short MEM2_Error              ;   yes, no fiddle
  143.     sub    bl, 2                ; Convert to Source error code
  144.     jmp    short MEM2_Error
  145. MEM2_InvCount:
  146.     mov    bl, ERR_LENINVALID
  147. MEM2_Error:
  148.     mov    byte ptr [bp.MEReturn], bl    ; Pass error code through
  149.     jmp    short MEM2_Exit
  150.  
  151. ;*******************************************************************************
  152. ;
  153. ; GetLinear286
  154. ;    Convert Handle and Offset (or 0 and SEG:OFFSET) into Linear address
  155. ;    Locks Handle if necessary
  156. ;    Nested with MoveExtended286 to access local variables
  157. ;
  158. ; Entry:
  159. ;    ES:BX    Points to structure containing:
  160. ;            Handle    dw
  161. ;            Offset    dd
  162. ;    [BP.Count]    Count of bytes to move
  163. ;
  164. ; Return:
  165. ;    BX    Handle of block (0 if conventional)
  166. ;    AX:DX    Linear address
  167. ;    CARRY    => Error
  168. ;        Error code in BL
  169. ;
  170. ; Registers Destroyed:
  171. ;    Flags, CX, DI
  172. ;
  173. ;-------------------------------------------------------------------------------
  174.  
  175. GetLinear286    proc    near
  176.     push    si
  177.     cli                    ; NO INTERRUPTS
  178.     mov    si, word ptr es:[bx+2]        ; Offset from start of handle
  179.     mov    di, word ptr es:[bx+4]        ; in DI:SI
  180.     mov    bx, word ptr es:[bx]        ; Handle in bx
  181.     or    bx, bx
  182.     jz    short GL2_Conventional
  183.  
  184.     test    [bx.Flags], USEDFLAG        ; Valid Handle?
  185.     jz    short GL2_InvHandle
  186.  
  187.     mov    ax, [bx.Len]            ; Length of Block
  188.     mov    cx, 1024
  189.     mul    cx                ; mul is faster on the 286
  190.     sub    ax, si
  191.     sbb    dx, di                ; DX:AX = max possible count
  192.     jc    short GL2_InvOffset              ; Base past end of block
  193.     sub    ax, word ptr [bp.Count]
  194.     sbb    dx, word ptr [bp.Count+2]
  195.     jc    short GL2_InvCount              ; Count too big
  196.  
  197.     inc    [bx.cLock]            ; Lock the Handle
  198.     mov    ax, [bx.Base]
  199.     mul    cx
  200.     add    ax, si                ; Linear address
  201.     adc    dx, di                ; in DX:AX
  202.  
  203. GL2_OKExit:
  204.     clc
  205. GL2_Exit:
  206.     sti
  207.     pop    si
  208.     ret
  209.  
  210. GL2_Conventional:
  211.     mov    ax, di                ; Convert SEG:OFFSET into
  212.     mov    dx, 16                ; 24 bit address
  213.     mul    dx
  214.     add    ax, si
  215.     adc    dx, 0                ; DX:AX has base address
  216.     mov    di, dx
  217.     mov    si, ax
  218.     add    si, word ptr [bp.Count]        ; Get End of Block + 1 in DI:SI
  219.     adc    di, word ptr [bp.Count+2]
  220.     cmp    di, 010h            ; 32-bit cmp
  221.     ja    short GL2_InvCount
  222.     jb    short GL2_OKExit
  223.     cmp    si, 0FFF0h
  224.     jbe    GL2_OKExit            ; Must be < 10FFEFh + 2
  225. GL2_InvCount:
  226.     mov    bl, ERR_LENINVALID
  227.     jmp    short GL2_Error
  228. GL2_InvHandle:
  229.     mov    bl, ERR_DHINVALID        ; Dest handle invalid
  230.     jmp    short GL2_Error
  231. GL2_InvOffset:
  232.     mov    bl, ERR_DOINVALID        ; Dest Offset invalid
  233. GL2_Error:
  234.     stc
  235.     jmp    short GL2_Exit
  236.     
  237. GetLinear286    endp
  238.  
  239. ;*******************************************************************************
  240. ;
  241. ; DoLoadAll
  242. ;    Use 286 LoadAll for copy - see warnings below
  243. ;    Nested within MoveExtended286
  244. ;
  245. ; Entry:
  246. ;    [BP.Count]    Word count for move
  247. ;    [BP.SrcLinear]    Linear address of the source
  248. ;    [BP.DstLinear]    Linear address of the destination
  249. ;
  250. ;    Interrupts are ON
  251. ;
  252. ; Return:
  253. ;    CARRY    => Error
  254. ;        Error code in BL
  255. ;
  256. ; Registers Destroyed:
  257. ;    Flags, AX, BX, CX, DX, SI, DI
  258. ;
  259. ;-------------------------------------------------------------------------------
  260.  
  261.     EVEN        ;* WORD alignment for data
  262.  
  263. ; Swap buffer for contents of 80:0
  264. cwBuffer  EQU    51
  265. rgwSwap80 DW    cwBuffer DUP (?)
  266.  
  267. ; LOADALL data buffer placed at 80:0
  268. ;
  269. LOADALL_TBL    LABEL    BYTE
  270.     DB    6 DUP(0)
  271. LDSW    DW    ?
  272.     DB    14 DUP (0)
  273. TR    DW    0
  274. LFLAGS    DW    0        ; High 4 bits 0, Int off, Direction clear
  275.                 ;   Trace clear. Rest don't care.
  276. LIP    DW    OFFSET    AFTER_LOADALL
  277. LDT    DW    0
  278. LDSS    DW    8000H
  279. LSSS    DW    80H
  280. LCSS    DW    ?
  281. LESS    DW    8000H
  282. LDI    DW    0
  283. LSI    DW    Offset rgwSwap80
  284. LBP    DW    0
  285. LSP    DW    ?
  286. LBX    DW    ?
  287. LDX    DW    ?
  288. LCX    DW    cwBuffer
  289. LAX    DW    80H
  290. ESDES    SEGREG_DESCRIPTOR <>
  291. CSDES    SEGREG_DESCRIPTOR <>
  292. SSDES    SEGREG_DESCRIPTOR <800H,0>
  293. DSDES    SEGREG_DESCRIPTOR <>
  294. GDTDES    DTR_DESCRIPTOR <>
  295. LDTDES    DTR_DESCRIPTOR <0D000H,0,0FFH,0088H>
  296. IDTDES    DTR_DESCRIPTOR <>
  297. TSSDES    DTR_DESCRIPTOR <0C000H,0,0FFH,0800H>
  298.  
  299. DescSaved    dw    -1        ; Flag for reentrancy
  300.  
  301. SaveDesc    macro    reg
  302.     push    word ptr [reg]        ; Save 3 word descriptor
  303.     push    word ptr [reg+2]    ; pointed to by reg
  304.     push    word ptr [reg+4]
  305.     endm
  306.  
  307. RestoreDesc    macro    reg
  308.     pop    word ptr [reg+4]    ; Restore 3 word descriptor
  309.     pop    word ptr [reg+2]    ; pointed to by reg
  310.     pop    word ptr [reg]
  311.     endm
  312.  
  313. NOP4    macro
  314.     sti                ; Faster than nop
  315.     sti
  316.     sti
  317.     sti
  318.     endm
  319.  
  320. DoLoadAll    proc    near
  321.  
  322. assume    cs:code, ds:code, es:nothing
  323.  
  324.     cld                    ;* just to be sure
  325.  
  326.     mov    ax, word ptr [bp.SrcLinear]    ; Create descriptors for source
  327.     mov    dl, byte ptr [bp.SrcLinear+2]    ; and destination of transfer
  328.     mov    cx, word ptr [bp.DstLinear]
  329.     mov    dh, byte ptr [bp.DstLinear+2]
  330.     xchg    [DSDES].SEG_BASE_LO,ax        ; Fill in table and pick up
  331.     xchg    [DSDES].SEG_BASE_HI,dl        ; old values
  332.     xchg    [ESDES].SEG_BASE_LO,cx
  333.     xchg    [ESDES].SEG_BASE_HI,dh
  334.  
  335.     mov    bx,Offset IDTDES
  336.     mov    si,Offset GDTDES
  337.  
  338.     inc    [DescSaved]
  339.     jz    short DLA_NoSave          ; Don't save old values first time
  340.     push    ax            ; Save these so we can be re-entrant
  341.     push    cx
  342.     push    dx
  343.