;**************************************************************
;***    XMSRAW.ASM                                          ***
;***                                                        ***
;***    function        XMS_Xms.rawMove(                    ***
;***                        dest:           DWord;          ***
;***                        source:         DWord;          ***
;***                        length:         Word)           ***
;***                        : Boolean;                      ***
;***                                                        ***
;***    Move a block of XM from source to dest. This call   ***
;***    uses physical addresses, and so the blocks must     ***
;***    be locked.                                          ***
;***                                                        ***
;**************************************************************

        .model  large,pascal 

        include xmsdefs.asm 

        extrn   errno:WORD  
        extrn   xmsHandler:DWord

;
;   Define entry point
;
        public  XMS_Xms@rawMove

        .data

;
;   Define the raw move packet:
;
movePacket  dd  0,0,0,0
segLength1  dw  ?
sourceAddr  db  ?,?,?
            db  XMSBiosAccess
            dw  0
segLength2  dw  ?
destAddr    db  ?,?,?
            db  XMSBiosAccess
            dw  0,0,0,0,0,0,0,0,0


        .code

XMS_Xms@rawMove proc    destHi:Word, destLo:Word, sourceHi:Word, sourceLo:WORD, xferLen:Word, self:DWord

        push    si                  ; Save SI

        mov     cx,xferLen          ; length in bytes of xfer
        mov     segLength1,cx
        mov     segLength2,cx

    ;
    ;   The bios call takes a number of words to move, so
    ;   we need to convert the byte count into a word count.
    ;   we give an error if the byte count was odd. We don't
    ;   want to round up, because this may be destructive.
    ;
        clc
        rcr     cx,1                ; shift right into carry
        jc      oddLength           ; special error case

    ;
    ;   Transfer the three byte (24 bit) physical addresses:
    ;
        mov     ax,destLo           ; LSB 2 bytes of dest
        mov     Word Ptr destAddr,ax
        mov     ax,destHi           ; MSB byte of dest
        mov     destAddr+2,al

        mov     ax,sourceLo         ; LSB 2 bytes of source
        mov     Word Ptr sourceAddr,ax
        mov     ax,sourceHi         ; MSB byte of source
        mov     sourceAddr+2,al

    ;
    ;   We're ready to do the call:
    ;
        push    ds                  ; get ES:SI = packet
        pop     es
        lea     si,movePacket

        mov     ah,XMSBiosXMMove    ; Function code
        int     XMSBios

        jc      errorReturn         ; Carry means error occurred

        mov     ax,XMSErrOK         ; No error
        pop     si                  ; restore SI
        ret

oddLength:
        mov     ah,XMSErrLenInv     ; Invalid length

errorReturn:
        mov     al,ah               ; Move error to AL
        xor     ah,ah               ; Zero extend error
        mov     errno,ax            ; Save in errno
        pop     si                  ; Restore SI
        ret

XMS_Xms@rawMove endp                ; end of procedure

        end




