home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / memory / himem / src / xm286.asm < prev    next >
Assembly Source File  |  1988-08-11  |  8KB  |  312 lines

  1. ;*******************************************************************************
  2. ;
  3. ; MoveExtended286
  4. ;    XMM Move Extended Memory Block for the 80286
  5. ;    Use Int 15h, Block Move
  6. ;
  7. ; Entry:
  8. ;    ES:BX    Points to a MoveExtendedStruc
  9. ;
  10. ; Return:
  11. ;    AX = 1    Success
  12. ;    AX = 0    Failure
  13. ;        Error Code in BL
  14. ;
  15. ; Registers Destroyed:
  16. ;    Flags
  17. ;
  18. ;            WARNING
  19. ;            =======
  20. ;
  21. ; This routine enables interrupts and can be re-entered
  22. ;
  23. ; Notes:
  24. ;    The case of copying from conventional to conventional memory
  25. ;    is not treated specially in this example.
  26. ;
  27. ; History:
  28. ;    Wed Jul 13 - AWG - Original version
  29. ;-------------------------------------------------------------------------------
  30. ifndef    XM286INCLUDED
  31. public    MoveExtMemory
  32. endif
  33. MoveExtMemory proc    near
  34.  
  35.     sti                    ; Be nice
  36.     push    bp                ; Set up stack frame so we
  37.     mov    bp, sp                ; can have local variables
  38.     sub    sp, 18+(6*8)            ; Space for local variables
  39. Count      = -4                    ; Local DWORD for byte count
  40. MEReturn  = -6                    ; Local WORD for return code
  41. SrcHandle = -8
  42. DstHandle = -10
  43. SrcLinear = -14
  44. DstLinear = -18
  45. GDT      = -18-(6*8)                ; Space for 6 GDT entries
  46.     pusha
  47.     push    ds
  48.     push    es
  49.  
  50.     xor    ax, ax
  51.     mov    [bp.MEReturn], ax            ; Assume success
  52.     mov    [bp.SrcHandle], ax
  53.     mov    [bp.DstHandle], ax
  54.     mov    ax, word ptr es:[si.bCount]    ; Pick up length specified
  55.     mov    word ptr [bp.Count], ax
  56.     mov    cx, word ptr es:[si.bCount+2]
  57.     mov    word ptr [bp.Count+2], cx
  58.     or    cx, ax
  59.     jcxz    short MEM2_Exit         ; Exit immediately if zero
  60.  
  61.     lea    bx, [si.SourceHandle]        ; Normalize Source
  62.     call    GetLinear286            ; Linear address in DX:AX
  63.     jc    short MEM2_SrcError        ; Have Dest Error Code
  64.     mov    word ptr [bp.SrcLinear], ax    ; Save Linear address
  65.     mov    word ptr [bp.SrcLinear+2], dx
  66.     mov    [bp.SrcHandle], bx        ; Save Handle for Unlock
  67.  
  68.     lea    bx, [si.DestHandle]        ; Normalize Destination
  69.     call    GetLinear286
  70.     jc    short MEM2_Error
  71.     mov    word ptr [bp.DstLinear], ax    ; Save Linear address
  72.     mov    word ptr [bp.DstLinear+2], dx
  73.     mov    [bp.DstHandle], bx        ; Save Handle for Unlock
  74.  
  75.     shr    word ptr [bp.Count+2], 1    ; Make word count
  76.     rcr    word ptr [bp.Count], 1
  77.     jc    short MEM2_InvCount        ; Odd count not allowed
  78.  
  79.         ;***********************************************;
  80.         ;                        ;
  81.         ; The XMS Spec states that a reasonable number    ;
  82.         ; of interrupt windows are guaranteed.  This    ;
  83.         ; loop should be tuned to provide such.        ;
  84.         ;                        ;
  85.         ;-----------------------------------------------;
  86.  
  87. MEM2_MoveLoop:
  88.     mov    cx, 512                ; Must be less than 8000h
  89.     cmp    word ptr [bp.Count+2], 0    ; Lots to do?
  90.     ja    short MEM2_MaxSize
  91.     cmp    word ptr [bp.Count], cx
  92.     jae    short MEM2_MaxSize
  93.     mov    cx, word ptr [bp.Count]        ; Just what is left
  94.     jcxz    short MEM2_Exit
  95. MEM2_MaxSize:
  96.     push    cx
  97.     call    DoMoveBlock
  98.     pop    cx
  99.     jc    short MEM2_Error
  100.     sub    word ptr [bp.Count], cx        ; Subtract what we just did
  101.     sbb    word ptr [bp.Count+2], 0
  102.     xor    dx, dx                ; Get byte count in DX:CX
  103.     shl    cx, 1
  104.     rcl    dx, 1
  105.     add    word ptr [bp.SrcLinear], cx
  106.     adc    word ptr [bp.SrcLinear+2], dx
  107.     add    word ptr [bp.DstLinear], cx
  108.     adc    word ptr [bp.DstLinear+2], dx
  109.     jmp    short MEM2_MoveLoop
  110.  
  111. MEM2_Exit:
  112.     pop    es
  113.     pop    ds
  114.     mov    bx, [bp.SrcHandle]        ; Unlock Handles if necessary
  115.     or    bx, bx
  116.     jz    short NoSrcHandle
  117.     dec    [bx.cLock]            ; Unlock Source
  118. NoSrcHandle:
  119.     mov    bx, [bp.DstHandle]
  120.     or    bx, bx
  121.     jz    short NoDstHandle
  122.     dec    [bx.cLock]            ; Unlock Destination
  123. NoDstHandle:
  124.     popa                    ; Restore original registers
  125.     mov    ax, 1
  126.     cmp    word ptr [bp.MEReturn], 0
  127.     jz    short MEM2_Success
  128.     dec    ax
  129.     mov    bl, byte ptr [bp.MEReturn]
  130. MEM2_Success:
  131.     mov    sp, bp                ; Unwind stack
  132.     pop    bp
  133.     ret
  134.  
  135. MEM2_SrcError:
  136.     cmp    bl, ERR_LENINVALID        ; Invalid count
  137.     je    short MEM2_Error        ;   yes, no fiddle
  138.     sub    bl, 2                ; Convert to Source error code
  139.     jmp    short MEM2_Error
  140. MEM2_InvCount:
  141.     mov    bl, ERR_LENINVALID
  142. MEM2_Error:
  143.     mov    byte ptr [bp.MEReturn], bl    ; Pass error code through
  144.     jmp    short MEM2_Exit
  145.  
  146. ;*******************************************************************************
  147. ;
  148. ; GetLinear286
  149. ;    Convert Handle and Offset (or 0 and SEG:OFFSET) into Linear address
  150. ;    Locks Handle if necessary
  151. ;    Nested with MoveExtended286 to access local variables
  152. ;
  153. ; Entry:
  154. ;    ES:BX    Points to structure containing:
  155. ;            Handle    dw
  156. ;            Offset    dd
  157. ;    [BP.Count]    Count of bytes to move
  158. ;
  159. ; Return:
  160. ;    BX    Handle of block (0 if conventional)
  161. ;    AX:DX    Linear address
  162. ;    CARRY    => Error
  163. ;        Error code in BL
  164. ;
  165. ; Registers Destroyed:
  166. ;    Flags, CX
  167. ;
  168. ;-------------------------------------------------------------------------------
  169.  
  170. GetLinear286    proc    near
  171.     push    si
  172.     push    di
  173.     cli                    ; NO INTERRUPTS
  174.     mov    si, word ptr es:[bx+2]        ; Offset from start of handle
  175.     mov    di, word ptr es:[bx+4]        ; in DI:SI
  176.     mov    bx, word ptr es:[bx]        ; Handle in bx
  177.     or    bx, bx
  178.     jz    short GL2_Conventional
  179.  
  180.     test    [bx.Flags], USEDFLAG        ; Valid Handle?
  181.     jz    short GL2_InvHandle
  182.  
  183.     mov    ax, [bx.Len]            ; Length of Block
  184.     mov    cx, 1024
  185.     mul    cx                ; mul is faster on the 286
  186.     sub    ax, si
  187.     sbb    dx, di                ; DX:AX = max possible count
  188.     jc    short GL2_InvOffset        ; Base past end of block
  189.     sub    ax, word ptr [bp.Count]
  190.     sbb    dx, word ptr [bp.Count+2]
  191.     jc    short GL2_InvCount        ; Count too big
  192.  
  193.     inc    [bx.cLock]            ; Lock the Handle
  194.     mov    ax, [bx.Base]
  195.     mul    cx
  196.     add    ax, si                ; Linear address
  197.     adc    dx, di                ; in DX:AX
  198.  
  199. GL2_OKExit:
  200.     clc
  201. GL2_Exit:
  202.     sti
  203.     pop    di
  204.     pop    si
  205.     ret
  206.  
  207. GL2_Conventional:
  208.     mov    ax, di                ; Convert SEG:OFFSET into
  209.     mov    dx, 16                ; 24 bit address
  210.     mul    dx
  211.     add    ax, si
  212.     adc    dx, 0                ; DX:AX has base address
  213.     mov    di, dx
  214.     mov    si, ax
  215.     add    si, word ptr [bp.Count]        ; Get End of Block + 1 in DI:SI
  216.     adc    di, word ptr [bp.Count+2]
  217.     cmp    di, 010h            ; 32-bit cmp
  218.     ja    short GL2_InvCount
  219.     jb    short GL2_OKExit
  220.     cmp    si, 0FFF0h
  221.     jbe    short GL2_OKExit        ; Must be < 10FFEFh + 2
  222. GL2_InvCount:
  223.     mov    bl, ERR_LENINVALID
  224.     jmp    short GL2_Error
  225. GL2_InvHandle:
  226.     mov    bl, ERR_DHINVALID        ; Dest handle invalid
  227.     jmp    short GL2_Error
  228. GL2_InvOffset:
  229.     mov    bl, ERR_DOINVALID        ; Dest Offset invalid
  230. GL2_Error:
  231.     stc
  232.     jmp    short GL2_Exit
  233.     
  234. GetLinear286    endp
  235.  
  236. ;*******************************************************************************
  237. ;
  238. ; DoMoveBlock
  239. ;    Set up GDT and call int 15h Move Block
  240. ;    Nested within MoveExtended286
  241. ;    See 80286 programmer's reference manual for GDT entry format
  242. ;    See Int 15h documentation for Move Block function
  243. ;
  244. ; Entry:
  245. ;    CX        Word count for move
  246. ;    [BP.SrcLinear]    Linear address of the source
  247. ;    [BP.DstLinear]    Linear address of the destination
  248. ;    [BP.GDT]    GDT for Block Move
  249. ;
  250. ;    Interrupts are ON
  251. ;
  252. ; Return:
  253. ;    CARRY    => Error
  254. ;        Error code in BL
  255. ;
  256. ; Registers Destroyed:
  257. ;    Flags, AX, CX
  258. ;
  259. ;-------------------------------------------------------------------------------
  260. DoMoveBlock    proc    near
  261.  
  262.     push    ds
  263.  
  264.     mov    ax, ss
  265.     mov    ds, ax
  266.     mov    es, ax
  267.  
  268.     lea    di, [bp.GDT]
  269.     mov    si, di                ; Parameter to Block Move
  270.     push    cx
  271.     mov    cx, 6*8/2            ; Words in the GDT
  272.     xor    ax, ax
  273.     rep    stosw                ; Clean it out
  274.  
  275.     lea    di, [bp.GDT+2*8]        ; Source Descriptor
  276.     dec    ax                ; Limit FFFFh
  277.     stosw
  278.     mov    ax, word ptr [bp.SrcLinear]
  279.     stosw
  280.     mov    al, byte ptr [bp.SrcLinear+2]
  281.     mov    ah, 93h                ; Access rights
  282.     stosw                    ; Source Descriptor done
  283.  
  284.     lea    di, [bp.GDT+3*8]        ; Destination Descriptor
  285.     mov    ax, 0FFFFh            ; Limit FFFFh
  286.     stosw
  287.     mov    ax, word ptr [bp.DstLinear]
  288.     stosw
  289.     mov    al, byte ptr [bp.DstLinear+2]
  290.     mov    ah, 93h                ; Access rights
  291.     stosw                    ; Destination Descriptor done
  292.  
  293.     pop    cx
  294.     mov    ah, 87h
  295.     int    15h                ; Block Move
  296.     jc    short DMB286_Error
  297. DMB_Exit:
  298.     pop    ds
  299.     ret
  300. DMB286_Error:
  301.     xor    bh, bh
  302.     mov    bl, al
  303.     mov    bl, cs:Int15Err286[bx]           ; Pick up correct error code
  304.     stc
  305.     jmp    short DMB_Exit
  306.  
  307. Int15Err286    db    0, ERR_PARITY, ERR_LENINVALID, ERR_A20
  308.  
  309. DoMoveBlock    endp
  310.  
  311. MoveExtMemory    endp
  312.