home *** CD-ROM | disk | FTP | other *** search
- 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
-