Category : Files from Magazines
Archive   : PJ91.ZIP
Filename : SWAP.ASM
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
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/