277 lines
4 KiB
NASM
277 lines
4 KiB
NASM
|
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
|