Category : Files from Magazines
Archive   : PJ91.ZIP
Filename : FILE.ASM

 
Output of file : FILE.ASM contained in archive : PJ91.ZIP
title file i/o for block storage
include asm.inc

public check_block_file
public open_block_file
public read_block_file
public set_block_handle


NULL_HANDLE equ 0
NULL_ID equ 0


file_str struc
f_next dd ?
f_size dd ?
f_index dw ? ; block index
f_id dw ?
file_str ends
f_name equ (size file_str)


.data?
file_list dd ?
file_end dd ?
file_count dw ?

current_id dw ?
current_handle dw ?


.const
ertx_file_id db 'Bad file id',0
ertx_file_missing db 'File missing',0
ertx_too_big db 'File too big',0


.code
extn move_file_pointer,set_strerror,read_from_file,open_input_file,save_most
extn close_file,strcmpi,input_file_size,strlenz,calloc,strcpy


;; change current file
;
; entry DX file id
; exit Cf if file not found
; uses SI,DS
;
change_current_file proc
pushm ax,bx
mov current_id[bp],NULL_ID

movx bx,NULL_HANDLE ; close current file
xchg bx,current_handle[bp]
cmpx bx,NULL_HANDLE
je ccf1 ; if no file open
call close_file

ccf1: lds si,file_list[bp]
jmp ccf3

ccf2: lds si,f_next[si] ; search file structures
ccf3: mov ax,ds
or ax,si
je ccf5 ; if file id not found
cmp dx,f_id[si]
jne ccf2 ; if wrong file, keep searching

lea si,f_name[si] ; open file
call open_input_file
jc ccf5

mov current_handle[bp],bx ; set handle and file id
mov current_id[bp],dx

ccf4: popm bx,ax
ret

ccf5: lea ax,ertx_file_missing ; *File missing*
call set_strerror
jmp ccf4
change_current_file endp


;; check block file
;
; entry DS:SI file name
; exit BX file id or 0 if unknown file
;
check_block_file proc
pushm di,es
les di,file_list[bp]
jmp cbf2

cbf1: les di,es:f_next[di]
cbf2: mov bx,es
or bx,di
stc
jz cbf3 ; if file not found
push di
lea di,f_name[di]
call strcmpi
pop di
jne cbf1 ; if wrong file
mov bx,es:f_id[di]
clc

cbf3: popm es,di
ret
check_block_file endp


;; current file size
;
; exit CX file size in 16k blocks
; Cf if unexpected error
; uses AX
;
current_file_size proc
pushm bx,dx
mov bx,current_handle[bp]
call input_file_size
jc cfs1 ; if unexpected error

mov cx,BLOCK_SIZE ; divide file size by 16k to get
cmp dx,cx ; block count
jae cfs2 ; if too many 16k blocks
div cx

add dx,-1 ; adjust count for partial block
adc ax,ZER0
mov cx,ax

cfs1: popm dx,bx
ret

cfs2: lea ax,ertx_too_big ; *File too big*
call set_strerror
jmp cfs1
current_file_size endp


;; link new file
;
; entry ES:DI file structure
; exit AX file structure count
;
link_new_file proc
inc file_count[bp]
mov ax,file_count[bp]
cmp ax,1
je lnf1 ; if first file structure

pushm si,ds ; else add new file structure to
lds si,file_end[bp] ; the end of the list
mov wptr f_next[si],di
mov wptr f_next[si+2],es
popm ds,si
jmp lnf2

lnf1: mov wptr file_list[bp],di ; set 1st entry in file structure list
mov wptr file_list[bp+2],es

lnf2: mov wptr file_end[bp],di ; set end of file structure list

mov wptr file_end[bp+2],es
ret
link_new_file endp


;; open block file
;
; entry DS:SI file name
; exit CX file size in 16k blocks
; DX file id (1..n)
; Cf if file not found or no storage
; uses AX
;
open_block_file proc
pushm bx,di,si,ds,es
call strlenz ; allocate file structure
add cx,size file_str
call calloc
jc obf1 ; if no memory

call link_new_file ; link file struct to end of file list
mov dx,ax
mov es:f_id[di],ax

lea di,f_name[di] ; copy file name into struct
call strcpy

call change_current_file ; close current file and open new file
jc obf1 ; if file not found

call current_file_size ; get number of 16k blocks in file

obf1: popm es,ds,si,di,bx
ret
open_block_file endp


;; read block file
;
; entry AX file block index (0..n)
; BX file id (1..n)
; ES:DI transfer address
; exit AX byte count
; Cf if error
;
read_block_file proc
call save_most
cmp bx,current_id[bp]
je rbf1 ; if file is already open

mov dx,bx ; else open file (new current file)
call change_current_file
jc rbf2 ; if file missing or other error

rbf1: mov cx,BLOCK_SIZE ; set file position
mul cx
mov bx,current_handle[bp]
call move_file_pointer
jc rbf2 ; if unexpected error

call read_from_file ; read block from file
rbf2: ret
read_block_file endp


;; set block handle
;
; entry BX block handle
; DX file id
; exit Cf if bad file id
; uses AX,CX,SI,DS
;
set_block_handle proc
mov cx,dx
jcxz sbh3 ; if bad file id

lds si,file_list[bp] ; advance through file structure list
jmp sbh2 ; to selected entry
sbh1: lds si,f_next[si]
sbh2: mov ax,ds
or ax,si ; (Cf=0)
jz sbh3 ; if bad file id
loop sbh1

mov f_index[si],bx
ret

sbh3: lea ax,ertx_file_id ; *Bad file id*
jmp set_strerror
set_block_handle endp

end


  3 Responses to “Category : Files from Magazines
Archive   : PJ91.ZIP
Filename : FILE.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. 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/