|
|
title HMem ;HMem.asm - huge memory functions HMemCpy, etc
include gpfix.inc include kernel.inc
externFP Int21Handler
DataBegin externW WinFlags ifdef WOW externD pFileTable externW cur_dos_PDB externW Win_PDB endif DataEnd
ifdef WOW externFP WOWFileRead externFP WOWFileWrite endif
sBegin CODE assumes cs,CODE
ifdef WOW externD prevInt21proc endif
externA __AHINCR
cProc hMemCpy,<PUBLIC,FAR>,<ds, si, di> parmD dest ; to ES:DI parmD src ; to DS:SI parmD cnt ; to DX:AX localW flags cBegin SetKernelDS mov bx, WinFlags mov flags, bx mov dx, seg_cnt ; DX:AX is 32 bit length mov ax, off_cnt xor cx, cx ; 0 if fault loading operands beg_fault_trap hmc_trap lds si, src les di, dest cld hmc_loop: mov cx, 8000h ; try to copy 32K
cmp cx, si ; space left in source? jae @F mov cx, si
@@: cmp cx, di ; space left in dest? jae @F mov cx, di
@@: neg cx ; convert bytes left to positive
or dx, dx ; >64K left to copy? jnz @F
cmp cx, ax ; At least this much left? jbe @F mov cx, ax
@@: sub ax, cx ; Decrement count while we're here sbb dx, 0
test flags, WF_CPU386 + WF_CPU486 + WF_ENHANCED jnz hmc_do32
shr cx, 1 ; Copy 32KB rep movsw adc cx, 0 rep movsb jmps hmc_copied
hmc_do32: .386p push cx shr cx, 2 rep movsd pop cx and cx, 3 rep movsb .286p
hmc_copied: mov cx, ax ; At end of copy? or cx, dx jz hmc_done
or si, si ; Source wrap-around? jnz @F mov bx, ds add bx, __AHINCR mov ds, bx
@@: or di, di ; Dest wrap-around? jnz @F mov bx, es add bx, __AHINCR mov es, bx end_fault_trap @@: jmps hmc_loop
hmc_trap: fault_fix_stack ; DX:AX = bytes left if failure krDebugOut DEB_ERROR, "hMemCopy: Copy past end of segment" add ax, cx adc dx, 0 hmc_done: ; DX:AX = 0 if success
cEnd
ifdef W_Q21 cProc _HREAD, <PUBLIC, FAR, NODATA>, <ds> parmW h parmD lpData parmD dwCnt cBegin SetKernelDS ds push bx mov bx, Win_PDB cmp bx, cur_dos_PDB je HR_PDB_ok
push ax mov cur_dos_PDB,bx mov ah,50h pushf call cs:prevInt21Proc ; JUMP THROUGH CS VARIABLE pop ax HR_PDB_OK: pop bx
cCall WowFileRead,<h,lpData,dwCnt,cur_dos_PDB,0,pFileTable>
; DX:AX = Number Bytes Read ; DX = FFFF, AX = Error Code
inc dx jnz @f
xor dx,dx or ax, -1 @@: dec dx cEnd
cProc _HWRITE, <PUBLIC, FAR, NODATA>, <ds> parmW h parmD lpData parmD dwCnt cBegin SetKernelDS ds
push bx ; Setting the DOS PDB can probably mov bx, Win_PDB ; be removed just pass Win_PDB to cmp bx, cur_dos_PDB ; the WOW thunk je HW_PDB_ok
push ax mov cur_dos_PDB,bx mov ah,50h pushf call cs:prevInt21Proc ; JUMP THROUGH CS VARIABLE pop ax HW_PDB_OK: pop bx
cCall WowFileWrite,<h,lpData,dwCnt,cur_dos_PDB,0,pFileTable>
; DX:AX = Number Bytes Read ; DX = FFFF, AX = Error Code
inc dx jnz @f
xor dx,dx or ax, -1 @@: dec dx cEnd
else public _HREAD, _HWRITE
_HREAD: mov bx, 3f00h jmps hugeIO
_HWRITE: mov bx, 4000h
cProc hugeIO, <FAR, NODATA>, <ds, si, di, cx> parmW h parmD lpData parmD dwCnt localD dwTot localW func cBegin mov func, bx ; read from a file mov bx, h xor cx, cx mov seg_dwTot, cx mov off_dwTot, cx beg_fault_trap hr_fault lds dx, lpData mov si, seg_dwCnt mov di, off_dwCnt
hr_loop: mov cx, 8000h ; try to do 32KB
cmp cx, dx ; space left in data buffer jae @F mov cx, dx neg cx
@@: or si, si ; at least 64K left jnz @F cmp cx, di jbe @F mov cx, di
@@: mov ax, func ; talk to DOS DOSCALL jc hr_oops
add off_dwTot, ax ; update transfer count adc seg_dwTot, 0
cmp ax, cx ; end of file? jnz hr_done
sub di, ax ; decrement count sbb si, 0
mov cx, si ; end of count or cx, di jz hr_done
add dx, ax ; update pointer to data jnz @F ; wrapped to next segment mov ax, ds add ax, __AHINCR mov ds, ax end_fault_trap @@: jmps hr_loop
hr_fault: pop dx pop ax ; krDebugOut DEB_ERROR, "File I/O past end of memory block" krDebugOut DEB_ERROR, "GP fault in _hread/_hwrite at #DX #AX" ; fault_fix_stack
hr_oops: or dx, -1 mov seg_dwTot, dx mov off_dwTot, dx
hr_done: mov dx, seg_dwTot mov ax, off_dwTot cEnd endif ; WOW
sEnd
end
|