home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microsft / xms20.arc / OEMSRC.ARC / XM386.ASM < prev   
Assembly Source File  |  1989-03-21  |  12KB  |  463 lines

  1. ;**************************************************************************
  2. ;*    * * * 386 PROTECT info * * *
  3. ;**************************************************************************
  4.  
  5. ;*    * 386 Descriptor template
  6. DESC386    STRUC
  7. limDesc386    dw    0        ; limit bits (0..15)
  8. LO_apDesc386    dw    0        ; base bits (0..15)
  9. MID_apDesc386    db    0        ; base bits (16..23)
  10. accessDesc386    db    0        ; accessDesc386 byte
  11. granDesc386    db    0        ; granularity byte
  12. HI_apDesc386    db    0        ; base bits (24..31)
  13. DESC386    ENDS
  14.  
  15. GDT386    STRUC
  16. limitGdt    dw    ?
  17. LO_apBaseGdt    dw    ?
  18. HI_apBaseGdt    dw    ?
  19. GDT386    ENDS
  20.  
  21. Zero segment use32 at 0
  22.     org    13*4
  23. Int13Vector    label    dword
  24. Zero    ends
  25.  
  26. ;MEM3_Code segment     use16 para public 'CODE'
  27. ;MEM3_Code ends
  28.  
  29. ;codeg     group     code, MEM3_Code
  30.  
  31. ;MEM3_Code segment
  32.     assume    cs:code, ds:code, es:nothing
  33.  
  34. MEM3_Start    label    byte    ; Start of relocatable code
  35. ;MEM3_Data     label     byte     ; Start of our data
  36.  
  37. MEM3_Offset    =    offset code:MEM3_Data-offset code:MEM3_Start
  38.  
  39. OurGDT    equ    byte ptr ($+MEM3_Offset)        ; Simple GDT
  40.         DESC386    <>
  41. descCS    equ    byte ptr ($+MEM3_Offset)
  42.         DESC386    <0FFFFh,0,0,09Fh,0,0>        ; Conforming CS
  43. descRealBig    equ    byte ptr ($+MEM3_Offset)
  44.         DESC386    <0FFFFh,0,0,093h,0cfh,0>    ; Page Granularity
  45.                             ; 4Gb Limit
  46. GDTLen    EQU ($+MEM3_Offset-OurGDT)
  47.  
  48. GDTPtr    equ    qword ptr ($+MEM3_Offset)
  49.         GDT386 <GDTLen,0,0>
  50.  
  51. OldInt13    equ    dword ptr ($+MEM3_Offset)
  52.         dd    0            ; Old contents of int 13 vector
  53.  
  54. GDTMoveBlock    equ byte ptr ($+MEM3_Offset)
  55.                         ; 386 Template OK for Move Block
  56.         DESC386    <>            ; Nul Descriptor
  57.         DESC386    <>            ; GDT Descriptor
  58. descSource    equ byte ptr ($+MEM3_Offset)
  59.         DESC386 <0FFFFh,0,0,93h,0,0>    ; Source Segment Descriptor
  60. descDest    equ byte ptr ($+MEM3_Offset)
  61.         DESC386 <0FFFFh,0,0,93h,0,0>    ; Destination Segment Descriptor
  62.         DESC386    <>            ; BIOS use
  63.         DESC386    <>            ; BIOS use
  64.  
  65. ;*******************************************************************************
  66. ;
  67. ; MoveExtended386
  68. ;    XMM Move Extended Memory Block for the 80386
  69. ;
  70. ; Entry:
  71. ;    ES:BX    Points to structure containing:
  72. ;        bCount        dd    ?    ; Length of block to move
  73. ;        SourceHandle    dw    ?    ; Handle for souce
  74. ;        SourceOffset    dd    ?    ; Offset into source
  75. ;        DestHandle    dw    ?    ; Handle for destination
  76. ;        DestOffset    dd    ?    ; Offset into destination
  77. ;
  78. ; Return:
  79. ;    AX = 1    Success
  80. ;    AX = 0    Failure
  81. ;        Error code in BL
  82. ;
  83. ; Registers Destroyed:
  84. ;    Flags
  85. ;
  86. ;-------------------------------------------------------------------------------
  87. MoveExtended386    proc    near
  88.  
  89.     sti                    ; Be nice
  90.     push    bp                ; Set up stack frame so we
  91.     mov    bp, sp                ; can have local variables
  92.     sub    sp, 18
  93. Count    = -4                    ; Local DWORD for byte count
  94. Return    = -6                    ; Local WORD for return code
  95. SrcHandle = -8
  96. DstHandle = -10
  97. SrcLinear = -14
  98. DstLinear = -18
  99.     push    eax                ; Save upper word of registers
  100.     push    ecx
  101.     push    esi
  102.     push    edi
  103.     push    bx
  104.  
  105.     xor    ax, ax
  106.     mov    [bp.Return], ax            ; Assume success
  107.     mov    [bp.SrcHandle], ax
  108.     mov    [bp.DstHandle], ax
  109.     mov    ecx, es:[si.bCount]
  110.     mov    [bp.Count], ecx
  111.  
  112.     shr    dword ptr [bp.Count], 1        ; No odd byte counts
  113.     jc    MEM3_InvCount
  114.     jz    MEM3_Exit            ; Exit immediately if zero
  115.  
  116.     lea    bx, [si.SourceHandle]        ; Normalize Source
  117.     call    GetLinear386            ; Linear address in edi
  118.     jc    MEM3_SrcError            ; Have Dest Error Code
  119.     xchg    esi, edi            ; Save source address in ESI
  120.     mov    [bp.SrcHandle], bx        ; Save Handle for Unlock
  121.  
  122.     lea    bx, [di.DestHandle]
  123.     call    GetLinear386            ; Normalize Destination
  124.     jc    MEM3_Error
  125.     mov    [bp.DstHandle], bx        ; Save Handle for Unlock
  126.  
  127.     smsw    ax
  128.     shr    ax, 1                ; Protected mode?
  129.     jc    MEM3_MoveBlock            ;   if so, use int 15h
  130.                         ; Must preserve DS
  131.  
  132.     call    word ptr ControlJumpTable[5*2]    ; Call LocalEnableA20()
  133.     cmp    ax, 1
  134.     jne    MEM3_Error
  135.  
  136.     xor    cx, cx
  137.     mov    es, cx
  138. assume    es:Zero
  139.     mov    ax, cs
  140.     shl    eax, 16
  141.     mov    ax, offset code:Int13Handler+MEM3_Offset
  142.     cli
  143.     push    [OldInt13]            ; For reentrancy
  144.     xchg    eax, [Int13Vector]        ; Install our int 13 handler
  145.     mov    [OldInt13], eax
  146.     sti
  147.  
  148.     push    ds
  149.     mov    ds, cx
  150. assume    ds:Zero
  151.     mov    ecx, [bp.Count]
  152.     shr    ecx, 1                ; Now DWORD count
  153.                         ; Odd word count in carry
  154.         ; Now we have:
  155.         ;    ESI = 32 bit Source Linear Address
  156.         ;    EDI = 32 bit Destination Linear Address
  157.         ;    DS = ES = 0
  158.         ; If the limit of DS or ES is still the Real Mode
  159.         ; default of 64k and ESI or EDI is greater than 64k,
  160.         ; these instructions will fault with an int 13.
  161.         ; In this case, our int 13 handler will set up
  162.         ; the descriptors to have 4Gb limits (real big mode)
  163.         ; and will iret to the faulting instruction.
  164.  
  165.         ; The following persuades masm to output
  166.         ; both a 66h and 67h prefix
  167. Fault0:
  168.     rep movs dword ptr [esi], dword ptr [edi]    ; DWORDS first
  169.             ; THE NEXT INSTRUCTION MUST HAVE ADDRESS SIZE OVERRIDE
  170.     db    67h        ; CHIP BUG - DO NOT REMOVE
  171.     nop            ; CHIP BUG - DO NOT REMOVE
  172.  
  173.     rcl    ecx, 1
  174. Fault1:
  175.     rep movs word ptr [esi], word ptr [edi]        ; Now the odd word
  176.             ; THE NEXT INSTRUCTION MUST HAVE ADDRESS SIZE OVERRIDE
  177.     db    67h        ; CHIP BUG - DO NOT REMOVE
  178.     nop            ; CHIP BUG - DO NOT REMOVE
  179.  
  180.     pop    ds
  181. assume    ds:code
  182.     pop    eax                ; saved [OldInt13]
  183.     cli                    ; NECESSARY
  184.     xchg    eax, [OldInt13]    ; OldInt13 potentially INVALID
  185.     mov    [Int13Vector], eax        ; Deinstall our handler
  186.     sti
  187.  
  188.     call    word ptr ControlJumpTable[6*2]    ; Call LocalDisableA20()
  189.     cmp    ax, 1
  190.     jne    short MEM3_Error
  191.     
  192. MEM3_Exit:
  193.     mov    bx, [bp.SrcHandle]        ; Unlock Handles if necessary
  194.     or    bx, bx
  195.     jz    short MEM3_NoSrcHandle
  196.     dec    [bx.cLock]            ; Unlock Source
  197. MEM3_NoSrcHandle:
  198.     mov    bx, [bp.DstHandle]
  199.     or    bx, bx
  200.     jz    short MEM3_NoDstHandle
  201.     dec    [bx.cLock]            ; Unlock Destination
  202. MEM3_NoDstHandle:
  203.     pop    bx                ; Restore original registers
  204.     pop    edi
  205.     pop    esi
  206.     pop    ecx
  207.     pop    eax
  208.     mov    ax, 1
  209.     cmp    word ptr [bp.Return], 0
  210.     je    short MEM3_Success
  211.     dec    ax                ; AX = 0 for error
  212.     mov    bl, byte ptr [bp.Return]
  213. MEM3_Success:
  214.     mov    sp, bp                ; Unwind stack
  215.     pop    bp
  216.     ret
  217.  
  218. MEM3_InvCount:
  219.     mov    bl, ERR_LENINVALID
  220.     jmp    short MEM3_Error
  221. MEM3_SrcError:
  222.     cmp    bl, ERR_LENINVALID        ; Invalid count
  223.     je    short MEM3_Error        ;   yes, no fiddle
  224.     sub    bl, 2                ; Convert to Source error code
  225. MEM3_Error:
  226.     mov    [bp.Return], bl
  227.     jmp    short MEM3_Exit
  228.  
  229. ;*******************************************************************************
  230. ;
  231. ; GetLinear386
  232. ;    Convert Handle and Offset (or 0 and SEG:OFFSET) into Linear address
  233. ;    Locks Handle if necessary
  234. ;    Nested with MoveExtended386 to access local variables
  235. ;
  236. ; Entry:
  237. ;    ES:BX    Points to structure containing:
  238. ;        Handle    dw
  239. ;        Offset    dd
  240. ;    ECX    Count of bytes to move
  241. ;
  242. ; Return:
  243. ;    BX    Handle of block (0 if conventional)
  244. ;    EDI    Linear address
  245. ;    CARRY    => Error
  246. ;
  247. ; Registers Destroyed:
  248. ;    EAX
  249. ;
  250. ;-------------------------------------------------------------------------------
  251.  
  252. GetLinear386    proc    near
  253.     cli                    ; NO INTERRUPTS
  254.     mov    edi, dword ptr es:[bx+2]    ; Offset from start of handle
  255.     mov    bx, word ptr es:[bx]        ; Handle in bx
  256.     or    bx, bx
  257.     jz    short GL3_Conventional
  258.  
  259.     cmp    [bx.Flags], USEDFLAG        ; Valid Handle?
  260.     jne    short GL3_InvHandle
  261.  
  262.     movzx    eax, [bx.Len]            ; Length of Block
  263.     shl    eax, 10                ; now in bytes
  264.     sub    eax, edi            ; EAX = max possible count
  265.     jb    short GL3_InvOffset        ; Base past end of block
  266.     cmp    eax, ecx
  267.     jb    short GL3_InvCount        ; Count too big
  268.  
  269.     inc    [bx.cLock]            ; Lock Handle
  270.     movzx    eax, [bx.Base]
  271.     shl    eax, 10                ; Base byte address
  272.     add    edi, eax            ; Linear address
  273.  
  274. GL3_OKExit:
  275.     clc
  276.     sti
  277.     ret
  278.  
  279. GL3_Conventional:
  280.     movzx    eax, di                ; Offset in EAX
  281.     shr    edi, 16
  282.     shl    edi, 4                ; Segment*16 in EDI
  283.     add    edi, eax            ; Linear address in EDI
  284.     mov    eax, edi
  285.     add    eax, ecx
  286.     cmp    eax, 10FFF0h            ; Max addressable inc. HMA
  287.     jbe    short GL3_OKExit
  288. GL3_InvCount:
  289.     mov    bl, ERR_LENINVALID
  290.     jmp    short GL3_Error
  291. GL3_InvHandle:
  292.     mov    bl, ERR_DHINVALID        ; Dest handle invalid
  293.     jmp    short GL3_Error
  294. GL3_InvOffset:
  295.     mov    bl, ERR_DOINVALID        ; Dest Offset invalid
  296. GL3_Error:
  297.     stc
  298.     sti
  299.     ret
  300.     
  301. GetLinear386    endp
  302.  
  303. ;*******************************************************************************
  304. ;
  305. ; Int13Handler
  306. ;    Handler for int 13 during our rep moves
  307. ;    If it is a real interrupt, jump to the old handler
  308. ;    If it is a fault, set Real Big Mode and return
  309. ;
  310. ; Entry:
  311. ;
  312. ; Return:
  313. ;
  314. ; Registers Destroyed:
  315. ;    BX, DS, ES if fault from one of our instructions, otherwise
  316. ;    NONE
  317. ;
  318. ;-------------------------------------------------------------------------------
  319.  
  320. Int13Handler    proc    far
  321. assume    cs:code, ds:nothing, es:nothing
  322.     push    bp
  323.     mov    bp, sp            ; Base to look at faulting address
  324.     push    ax
  325.  
  326.     mov    al, 0Bh            ; Party on PIC to see if interrupt
  327.     out    20h, al
  328.     in    al, 20h            ; ISR
  329.     test    al, 20h            ; IRQ5, int 13
  330.     jnz    short NotOurInt13
  331.  
  332.     mov    ax, cs
  333.     cmp    [bp+4], ax        ; Fault from our cs?
  334.     jne    short NotOurInt13    ;   no, SOMETHING IS FUNNY!
  335.     cmp    word ptr [bp+2], offset code:Fault0+MEM3_Offset
  336.     je    short LoadDescriptorCache
  337.     cmp    word ptr [bp+2], offset code:Fault1+MEM3_Offset
  338.     jne    short NotOurInt13    ; Not one of our instructions ????
  339.  
  340. LoadDescriptorCache:
  341.     mov    bx, descRealBig - OurGDT    ; Special 4Gb selector
  342.     lgdt    qword ptr cs:[GDTPtr]
  343.  
  344.     mov    eax, cr0
  345.     or    al,1
  346.     mov    cr0, eax            ; Go into Protected Mode
  347.                         ; NOTE: NMIs will kill us!!!
  348.  
  349.     db    0eah                ; jmp far flush_prot
  350.     dw    offset code:flush_prot+MEM3_Offset     ; Clears the prefetch
  351.     dw    descCS - OurGDT    
  352.  
  353. flush_prot:
  354.     mov    es, bx                ; Set up the segments we want
  355.     mov    ds, bx
  356.  
  357.     and    al, 0FEh
  358.     mov    cr0, eax            ; Return to Real Mode
  359.  
  360.     db    0EAH            ; jmp far flush_real
  361.     dw    offset code:flush_real+MEM3_Offset
  362. patch3    equ word ptr ($+MEM3_Offset)
  363.     dw    0
  364.  
  365. flush_real:
  366.     xor    ax, ax
  367.     mov    ds, ax
  368.     mov    es, ax
  369.  
  370.     pop    ax
  371.     pop    bp
  372.     iret                    ; Back to faulting instruction
  373.  
  374. NotOurInt13:
  375.     pop    ax
  376.     pop    bp
  377.     jmp    cs:[OldInt13]
  378.  
  379. Int13Handler    endp
  380.  
  381. ;*******************************************************************************
  382. ;
  383. ; MEM3_MoveBlock
  384. ;    Set up GDT and call int 15h Move Block
  385. ;    Nested within MoveExtended386
  386. ;    See 80286 programmer's reference manual for GDT entry format
  387. ;    See Int 15h documentation for Move Block function
  388. ;
  389. ; Entry:
  390. ;    [BP.Count]    Word count for move
  391. ;    ESI        Linear address of the source
  392. ;    EDI        Linear address of the destination
  393. ;
  394. ;    Interrupts are ON
  395. ;
  396. ; Return:
  397. ;    CARRY    => Error
  398. ;        Error code in BL
  399. ;
  400. ; Registers Destroyed:
  401. ;    Flags, EAX, ECX, ESI, EDI, ES
  402. ;
  403. ;-------------------------------------------------------------------------------
  404. MEM3_MoveBlock:
  405. assume    ds:code
  406.     mov    [bp.SrcLinear], esi
  407.     mov    [bp.DstLinear], edi
  408.     mov    ax, ds
  409.     mov    es, ax
  410. assume    es:code
  411.  
  412. DMB_loop:
  413.     mov    ecx, 512            ; Do max of # words left or
  414.     cmp    ecx, [bp.Count]            ; or max Move Block allows
  415.     jbe    short DMB0
  416.     mov    ecx, [bp.Count]
  417. DMB0:
  418.     push    ecx
  419.     lea    si, [GDTMoveBlock]    ; Pointer to GDT for Block Move
  420.  
  421.     lea    di, [descSource.LO_apDesc386]    ; Source Descriptor
  422.     mov    eax, dword ptr [bp.SrcLinear]
  423.  
  424.     CLI                    ; No interrupts until int 15h
  425.                         ; Allows reentrancy
  426.     stosw
  427.     shr    eax, 16
  428.     stosb                    ; Source Descriptor done
  429.  
  430.     lea    di, [descDest.LO_apDesc386]    ; Destination Descriptor
  431.     mov    eax, dword ptr [bp.DstLinear]
  432.     stosw
  433.     shr    eax, 16
  434.     stosb                    ; Destination Descriptor done
  435.  
  436.     clc                ; MUST DO THIS, int 15h doesn't bother
  437.     mov    ah, 87h            ; Block Move - Assumes protect
  438.     int    15h            ; mode code will allow interrupts
  439.  
  440.     STI
  441.     pop    ecx
  442.     jc    short DMB_Error
  443.  
  444.     sub    [bp.Count], ecx
  445.     jz    MEM3_Exit            ; All done
  446.     shl    ecx, 1                ; Back to byte count
  447.     add    [bp.SrcLinear], ecx        ; Update source for next chunk
  448.     add    [bp.DstLinear], ecx        ; Update destination
  449.     jmp    short DMB_loop
  450.  
  451. DMB_Error:
  452.     xor    bh, bh
  453.     mov    bl, al
  454.     mov    bl, cs:[Int15Err][bx]        ; Pick up correct error code
  455.     jmp    MEM3_Error
  456.  
  457. Int15Err    equ    byte ptr ($+MEM3_Offset)
  458.         db    0, ERR_PARITY, ERR_LENINVALID, ERR_A20
  459.  
  460. MoveExtended386    endp
  461.  
  462. MEM3_End    label    byte        ; End of relocatable code
  463.