home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
progjour
/
1991
/
01
/
swap.asm
< prev
next >
Wrap
Assembly Source File
|
1990-11-01
|
5KB
|
247 lines
title swap file manager
include asm.inc
public swap_in ; swap block from file to ram
public swap_out ; swap block from ram to file
NULL_SWAP equ 0
SWAP_MAX equ 1024 ; 16 megabytes of swap space
XPB segment word public 'DATA' ; close and delete swap file on exit
XPB ends
XP segment word public 'DATA'
dw on_exit_swap
XP ends
XPE segment word public 'DATA'
XPE ends
XCB segment word public 'DATA' ; just delete swap file on termination
XCB ends
XC segment word public 'DATA'
dw on_terminate_swap
XC ends
XCE segment word public 'DATA'
XCE ends
.const
ertx_swap_full db 'Swap space full',0
ertx_swap_read db 'Swap read',0
.data?
swap_icount dw ? ; number of blocks swapped in
swap_ocount dw ? ; number of blocks swapped out
swap_handle dw ? ; swap file handle
swap_bits db SWAP_MAX/8 dup(?)
swap_fname db FILENAME_MAX dup(?)
.code
extn close_file,dialog_error_beta,move_file_pointer,ms_dos_dialog
extn read_from_file,remove,save_most,err_disk_full
;; create swap file
;
; exit BX file handle (swap_handle set)
; uses AX,CX,DX
;
create_swap_file proc
push ds
mov ah,5Ah ; create uniquely named file
movx cx,0
lea dx,swap_fname
movx ds,DGROUP_SEGMENT
mov swap_fname[bp],NULL_CHAR
call ms_dos_dialog
jc csf1 ; if create failed
mov swap_handle,ax ; (DS==DGROUP here)
mov bx,ax ;\
csf1: pop ds
ret
create_swap_file endp
;; get swap index
;
; exit AX swap index (0..MAX-1)
; Cf if swap file full
;
get_swap_index proc
pushm cx,si
mov al,1
mov cx,SWAP_MAX
lea si,swap_bits-1
even ; search swap bits for next free index
gwi1: ror al,1
adc si,ZER0
test al,[bp+si]
loopnz gwi1
jnz gwi3 ; if no handles left (swap space full)
or [bp+si],al
mov ax,SWAP_MAX-1
sub ax,cx
gwi2: popm si,cx
ret
gwi3: lea ax,ertx_swap_full ; *Swap space full*
call dialog_error_beta
jmp gwi2
get_swap_index endp
;; on exit swap
;
; uses AX,BX,SI,DS
;
on_exit_swap proc
mov bx,swap_handle[bp]
cmpx bx,NULL_HANDLE
je oes1 ; if no swap file
call close_file
oes1: ret
on_exit_swap endp
;; on terminate swap
;
; uses AX,CX,SI,DS
;
on_terminate_swap proc
movx cx,NULL_HANDLE ; (during exit intercept, this proc
xchg cx,swap_handle[bp] ; may execute under COMMAND.COM's PSP)
jcxz ots1 ; if no swap file
movx ds,DGROUP_SEGMENT ; else delete swap file (notice that
lea si,swap_fname ; swap file is already closed by
call remove ; dos terminator or on_exit routine)
ots1: ret
on_terminate_swap endp
;; swap in
;
; entry AX swap index
; ES:DI destination (no disk I/O if NULL)
; exit Cf if error
; uses AX
;
swap_in proc
call save_most
dec ax ; clear swap index bit
js sin1 ; if bad swap index (cannot be -)
mov si,ax
mov cl,3 ; (divide bit number by 8 to select
shr si,cl ; byte)
mov cl,al ; (use the 3 least significant bits
and cl,7 ; to rotate a mask)
mov ch,10000000b
ror ch,cl
test swap_bits[bp+si],ch
jz sin1 ; if bad swap index (internal error)
xor swap_bits[bp+si],ch
mov cx,es ; do not read swap file if NULL output
jcxz sin2 ; if NULL destination
mov bx,swap_handle[bp]
cmpx bx,NULL_HANDLE
je sin1 ; if no handle (internal error)
mov cx,BLOCK_SIZE ; position swap pointer
mul cx
call move_file_pointer
jc sin2
call read_from_file ; read block from swap file
jc sin2
inc swap_icount[bp]
cmp ax,cx
je sin2 ; if full 16k block read from file
sin1: lea ax,ertx_swap_read ; *Swap read*
call dialog_error_beta
sin2: ret
swap_in endp
;; swap out
;
; entry ES:DI source pointer
; exit AX swap index (1..MAX) or 0 if error
; Cf if error (full disk or swap file, not DOS 3+)
;
swap_out proc
call save_most
mov bx,swap_handle[bp]
cmpx bx,NULL_HANDLE
je out2 ; if no swap file
out1: call get_swap_index
jc out3 ; if swap file full
mov si,ax
inc si ; (offset swap index by 1)
mov cx,BLOCK_SIZE ; position swap file pointer
mul cx
call move_file_pointer
jc out3 ; if unlikely dos error
call write_swap_file ; write block to swap file
jc out3 ; if disk full
inc swap_ocount[bp]
mov ax,si
ret
out2: call create_swap_file
jnc out1
out3: mov ax,si ; clear swap bit
movx di,NULL_POINTER
mov es,di
call swap_in
movx ax,NULL_SWAP
stc
ret
swap_out endp
;; write swap file
;
; entry BX file handle
; CX byte count
; ES:DI source
; exit Cf if error
; uses AX
;
write_swap_file proc
mov ah,40h
pushm ds,es
pop ds
xchg dx,di
call ms_dos_dialog
xchg dx,di
pop ds
jc wsf1 ; if error
cmp ax,cx
je wsf1 ; if successful (Cf==0)
jmp err_disk_full ; else disk full
wsf1: ret
write_swap_file endp
end