mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 01:14:21 +00:00
1494 lines
37 KiB
Plaintext
1494 lines
37 KiB
Plaintext
;******************** bdos file system part 3 ****************
|
|
;
|
|
;
|
|
sqread:
|
|
;sequential disk read operation
|
|
mov seqio,1
|
|
;drop through to diskread
|
|
;
|
|
diskread: ;(may enter from seqdiskread)
|
|
CALL TST_INV_FCB ;VERIFY FCB HAS NOT BEEN FLAGGED
|
|
;AS INVALID
|
|
mov rmf,true ;read mode flag =
|
|
;true (open$reel)
|
|
;read the next record from
|
|
;the current fcb
|
|
|
|
if MPM
|
|
|
|
MOV DONT_CLOSE,TRUE
|
|
|
|
endif
|
|
|
|
call getfcb ;sets parameters for the read
|
|
DISK_READ0:
|
|
mov al,vrecord
|
|
cmp al,rcount ;vrecord-rcount
|
|
;skip if rcount > vrecord
|
|
jb recordok
|
|
|
|
if MPM
|
|
|
|
;IF FCB WAS OPENED IN UNLOCKED MODE, CHECK THE DIRECTORY FCB
|
|
;TO MAKE SURE ANOTHER PROCESS HAS NOT ALLOCATED A BLOCK TO
|
|
;THE FCB SINCE THIS PROCESS OPENED THE FCB
|
|
|
|
CALL TEST_DISK_FCB ;JUMP BACK TO DISKREAD0 IF DONT_CLOSE
|
|
JNZ DISKREAD0 ;TRUE, FILE OPENED IN UNLOCKED MODE,
|
|
;AND ACCESS OF DIR FCB SUCCESSFUL
|
|
;DONT_CLOSE SET TO FALSE
|
|
MOV AL,VRECORD
|
|
|
|
endif
|
|
;not enough records in extent
|
|
;record count must be 128
|
|
;to continue
|
|
cmp al,128 ;vrecord = 128?
|
|
jnz diskeof ;skip if vrecord<>128
|
|
call openreel ;go to next extent if so
|
|
; mov vrecord,0 ;vrecord=00
|
|
;now check for open ok
|
|
cmp lret,0 ;stop at eof
|
|
jnz diskeof
|
|
recordok:
|
|
;arrive with fcb addressing a record to read
|
|
call index
|
|
;error 2 if reading
|
|
;unwritten data
|
|
;(returns 1 to be compatible
|
|
;with 1.4)
|
|
call alloct ;arecord=0000?
|
|
|
|
if MPM
|
|
|
|
JNZ RECORDOK1
|
|
CALL TEST_DISK_FCB ;JUMP BACK TO DISKREAD0 IF DONT_CLOSE
|
|
JNZ DISKREAD0 ;TRUE, FILE OPENED IN UNLOCKED MODE,
|
|
;AND ACCESS OF DIR FCB SUCCESSFUL
|
|
endif
|
|
jz diskeof
|
|
|
|
RECORDOK1:
|
|
;record has been allocated,
|
|
;read it
|
|
call atran ;arecord now a disk address
|
|
call seek ;to proper track,sector
|
|
call rdbuff ;to dma address
|
|
jmp setfcb ;replace parameter
|
|
; ret
|
|
diskeof:
|
|
jmp setlret1 ;lret = 1
|
|
;ret
|
|
|
|
if MPM
|
|
|
|
TEST_DISK_FCB:
|
|
|
|
TEST HIGH_EXT,80H ;WAS FILE OPENED IN UNLOCKED MODE
|
|
JZ RET14 ;NO
|
|
TEST DONT_CLOSE,0FFH ;RETURN IF DONT_CLOSE FALSE
|
|
JZ RET14
|
|
CALL CLOSE1 ;FCB IN MEMORY
|
|
TEST_DISK_FCB1:
|
|
POP SI
|
|
MOV BX,OFFSET LRET
|
|
CMP B[BX],0FFH
|
|
MOV AL,11
|
|
JNE $+5
|
|
JMP STA_RET ;ERROR - CLOSE OPERATION UNSUCCESSFUL
|
|
MOV B[BX],0 ;LRET = 0
|
|
PUSH SI
|
|
CALL GET_RCNTA
|
|
MOV AL,[BX]
|
|
MOV RCOUNT,AL
|
|
XOR AL,AL
|
|
MOV DONT_CLOSE,AL ;DONT_CLOSE = FALSE
|
|
INC AL ;SUCCESSFUL OPERATION, RESET ZERO FLAG
|
|
RET
|
|
|
|
endif
|
|
|
|
;
|
|
|
|
RESET_FWF:
|
|
call getmodnum ;bx=.fcb(modnum)
|
|
;al=fcb(modnum)
|
|
;reset the fcb write flag to
|
|
;mark as written fcb
|
|
and al,not fwfmsk ;high order bit of modnum fld reset
|
|
mov [bx],al ;fcb(modnum) = fcb(modnum) & 7fh
|
|
RET14: RET
|
|
|
|
|
|
sqwrite:
|
|
;sequential disk write
|
|
mov seqio,1
|
|
;drop through to diskwrite
|
|
;
|
|
diskwite: ;(may enter here from
|
|
;seqdiskwrite above)
|
|
mov rmf,false ;read mode flag
|
|
;write record to currently
|
|
;selected file
|
|
call checkwrite ;in case write protected
|
|
|
|
TEST XFCB_READ_ONLY,TRUE ;READ/ONLY ERROR IF XFCB_READ_ONLY TRUE
|
|
MOV AL,3 ;XFCB_READ_ONLY TRUE IF FILE IS
|
|
JZ $+5 ;PASSWORD PROTECTED IN WRITE MODE
|
|
;AND PASSWORD WAS NOT SUPPLIED
|
|
;WHEN THE FILE WAS OPENED.
|
|
JMP_SET_ARET:
|
|
JMP SET_ARET
|
|
TEST HIGH_EXT,40H ;READ/ONLY ERROR IF FCB OPENED
|
|
JNZ JMP_SET_ARET ;IN READ/ONLY MODE
|
|
|
|
mov bx,info ;bx = .fcb(0)
|
|
call ckrofile ;may be a read-only file
|
|
|
|
CALL TST_INV_FCB ;TTEST FOR VALID FCB
|
|
|
|
call getfcb ;to set local parameters
|
|
mov al,vrecord
|
|
cmp al,lstrec+1 ;vrecord-128
|
|
;skip if vrecord > lstrec
|
|
;vrecord = 128, cannot open
|
|
;next extent
|
|
jb dskwr0
|
|
CALL OPEN_REEL ;TRY TO OPEN NEXT EXTENT
|
|
TEST LRET,TRUE
|
|
JNZ RET14
|
|
dskwr0:
|
|
;
|
|
if MPM
|
|
|
|
MOV DONT_CLOSE,TRUE
|
|
DISK_WRITE1:
|
|
|
|
endif
|
|
|
|
call index
|
|
call alloct
|
|
|
|
if MPM
|
|
|
|
JZ DISKWRITE2
|
|
|
|
;IF FILE IS UNLOCKED, VERIFY RECORD IS NOT LOCKED
|
|
;RECORD HAS TO BE ALLOCATED TO BE LOCKED
|
|
|
|
TEST HIGH_EXT,80H ;WAS FILE OPENED IN UNLOCKED MODE?
|
|
JZ NOT_UNLOCKED ;NO
|
|
CALL ATRAN
|
|
MOV CH,MULT_CNT ;TEST_LOCK EXPECTS MULT_CNT
|
|
PUSH CX ;PUSHED ON STACK
|
|
CALL TEST_LOCK ;VERIFY RECORD IS NOT LOCKED BY
|
|
;ANOTHER PROCESS
|
|
POP CX
|
|
MOV WFLAG,0
|
|
JMPS DISKWR10
|
|
NOT_UNLOCKED:
|
|
OR AL,TRUE ;RESET Z FLAG FOR FOLLOWING JNZ
|
|
|
|
endif
|
|
|
|
mov cl,0 ;marked as normal write
|
|
;operation for wrbuff
|
|
jnz dskwr1
|
|
|
|
if MPM
|
|
|
|
DISK_WRITE2:
|
|
CALL TEST_DISK_FCB ;JUMP BACK TO DISK_WRITE1 IF
|
|
;DONT_CLOSE IS TRUE, FILE WAS OPENED
|
|
;IN UNLOCKED MODE, AND ACCESS OF
|
|
;DIR FCB WAS SUCCESSFUL
|
|
|
|
JNZ DISK_WRITE1
|
|
|
|
endif
|
|
|
|
;not allocated:
|
|
;the argument to getblock is the starting
|
|
;position for the disk search, and should be
|
|
;the last allocated block for this file, or
|
|
;the value 0 if no space has been allocated
|
|
;
|
|
call dmposition
|
|
mov dminx,al ;save for later
|
|
xor cx,cx ;may use block zero
|
|
or al,al
|
|
jz nopblock ;skip if no previous block
|
|
;previous block exists at a
|
|
mov cl,al
|
|
dec cx
|
|
call getdm ;previous block # to bx
|
|
mov cx,bx ;cx=prev block#
|
|
nopblock:
|
|
;cx = 0, or previous block #
|
|
call getblock ;block # to bx
|
|
;arrive with block# or zero
|
|
or bx,bx
|
|
jnz blockok
|
|
;cannot find block to allocate
|
|
mov al,2
|
|
jmp staret ;lret=2
|
|
blockok:
|
|
MOV COMP_FCB_CKS,TRUE ;MUST RECOMPUTE FCB CHECKSUM
|
|
;bx contains allocated block #
|
|
mov arecord,bx
|
|
xchg bx,dx ;block number to dx
|
|
mov bx,info
|
|
add bx,dskmap ;bx=.fcb(diskmap)
|
|
cmp single,0 ;set flags for single byte dm
|
|
mov al,dminx ;recall dm index
|
|
mov ah,0
|
|
jz allocwd ;skip if allocating word
|
|
;allocating a byte value
|
|
add bx,ax
|
|
mov [bx],dl ;single byte alloc
|
|
jmps dskwru ;to continue
|
|
allocwd:
|
|
;allocate a word value
|
|
add bx,ax
|
|
add bx,ax ;bx=.fcb(dminx*2)
|
|
mov [bx],dx ;double wd
|
|
inc bx
|
|
dskwru:
|
|
;disk write to previously unallocated block
|
|
mov cl,2 ;marked as unallocated write
|
|
dskwr1:
|
|
;continue the write operation of no allocation error
|
|
;c = 0 if normal write, 2 if to prev unalloc block
|
|
;
|
|
; cmp lret,0
|
|
; jz dskwr10
|
|
; ret
|
|
;dskwr10: ;stop if non zero value
|
|
mov wflag,cl ;save the write flag
|
|
call atran ;arecord set
|
|
DISKWR10:
|
|
cmp seqio,2 ;check random with 0 fill
|
|
jnz dskw11
|
|
;
|
|
; this is random write with zero fill
|
|
;
|
|
cmp wflag,2 ;check for new allocation
|
|
jnz dskw11 ;old allocation
|
|
;
|
|
; new alloction for random with zero fill
|
|
;
|
|
mov di,buffa
|
|
xor ax,ax ;zero and fill
|
|
mov cx,64 ;zero 64 words in dirbuf
|
|
rep stos ax
|
|
call setdir
|
|
PUSH ARECORD ;SAVE ARECORD
|
|
mov bx,ablock
|
|
fill1: mov arecord,bx
|
|
call seek
|
|
;reg cl used for deblocking
|
|
call wrbufflg ;write fill record
|
|
mov bx,arecord ;restore last record
|
|
mov wflag,0 ;change allocate flag
|
|
mov al,bl ;arecord in bx
|
|
mov dh,blkmsk
|
|
and al,dh
|
|
inc bx
|
|
cmp al,dh
|
|
jnz fill1 ;cont until cluster is zeroed
|
|
POP ARECORD ;RESTORE ARECORD
|
|
MOV WFLAG,2 ;RESTORE WFLAG
|
|
call setdata
|
|
dskw11:
|
|
call seek ;to proper file position
|
|
;(cl=2 if new block,0 if not)
|
|
|
|
;SET WFLAG TO ZERO IF VRECORD
|
|
MOV AL,VRECORD ;DOES NOT SPECIFY 1ST RECORD OF
|
|
MOV AH,BLKMSK ;NEW BLOCK
|
|
AND AH,AL
|
|
JZ WRITE
|
|
MOV WFLAG,0
|
|
WRITE:
|
|
CALL WRBUFFLG ;written to disk
|
|
;increment record count
|
|
;if rcount <= vrecord
|
|
mov al,vrecord
|
|
mov bx,offset rcount
|
|
cmp al,[bx] ;vrecord-rcount
|
|
jb dskwr2
|
|
;rcount <= vrecord
|
|
mov [bx],al
|
|
inc b[bx] ;rcount = vrecord+1
|
|
|
|
if MPM
|
|
|
|
TEST HIGH_EXT,80H
|
|
JZ WRITE1
|
|
|
|
;FOR UNLOCKED FILE
|
|
; RCOUNT = VRECORD & (~ BLKMSK) + BLKMSK + 1
|
|
|
|
MOV CH,BLKMSK
|
|
MOV CL,CH
|
|
NOT CL
|
|
INC CH
|
|
AND AL,CL
|
|
ADD AL,CH
|
|
MOV [BX],AL
|
|
WRITE1:
|
|
|
|
endif
|
|
|
|
MOV WFLAG,2 ;mark as record count
|
|
;incremented
|
|
dskwr2:
|
|
CMP WFLAG,2 ;WFLAG=2 IF NEW BLOCK OR NEW RECORD #
|
|
JNZ NOUPDATE
|
|
|
|
if MPM
|
|
|
|
TEST HIGH_EXT,80H ;IS FILE OPEN MODE UNLOCKED?
|
|
JZ DSKWR2A
|
|
MOV AL,[BX]
|
|
CALL GET_RCNTA ;RESTORE FCB(RCOUNT)
|
|
MOV [BX],AL
|
|
CALL CLOSE
|
|
CALL TEST_DISK_FCB1
|
|
DSKWR2A:
|
|
|
|
endif
|
|
|
|
CALL RESET_FWF
|
|
|
|
noupdate:
|
|
CALL GETMODNUM ;SET FILE WRITE FLAG IF RESET
|
|
AND AL,40H
|
|
JNZ DSKWR3
|
|
OR B[BX],40H
|
|
CALL RESET_FWF ;RESET FCB WRITE FLAG TO ENSURE
|
|
;T3' GETS RESET BY THE CLOSE FUNCTION
|
|
dskwr3:
|
|
jmp setfcb ;replace parameters
|
|
;ret
|
|
;
|
|
rseek:
|
|
;random access seek operation, c=0ffh if read mode
|
|
;fcb is assumed to address an active fcb
|
|
;(modnum has been set to 1100$0000b if previous bad seek)
|
|
;
|
|
mov seqio,0 ;marked as random access op.
|
|
rseek1:
|
|
push cx ;save r/w flag
|
|
mov dx,info
|
|
;dx will hold base of fcb
|
|
mov bx,ranrec
|
|
add bx,dx ;bx=.fcb(ranrec)
|
|
mov al,[bx]
|
|
and al,7fh
|
|
push ax ;record number
|
|
mov al,[bx]
|
|
rcl al,1 ;cy=lsb of extent#
|
|
inc bx
|
|
MOV CH,[BX]
|
|
RCL CH,1
|
|
AND CH,11111B ;CH=EXT#
|
|
;CH holds extent number,
|
|
;record stacked
|
|
MOV AL,[BX]
|
|
AND AL,11110000B
|
|
INC BX
|
|
OR AL,[BX]
|
|
MOV CL,4
|
|
ROL AL,CL
|
|
MOV CL,AL
|
|
XCHG CH,CL ;CH=MOD#, CL=EXT#
|
|
|
|
pop ax ;recall sought record #
|
|
|
|
MOV AH,[BX] ;HIGH BYTE OF RR FIELD MUST
|
|
AND AH,11111100B ;BE <= 3
|
|
|
|
mov bl,6 ;zero flag, l=6
|
|
;produce error 6,
|
|
;seek past physical eod
|
|
JZ $+5
|
|
JMP SEEKERR
|
|
;otherwise, high byte = 0
|
|
mov bx,nxtrec
|
|
add bx,dx ;bx=.fcb(nxtrec)
|
|
mov [bx],al ;sought rec# stored away
|
|
;
|
|
;arrive here with ch=mod#, cl=ext#, dx=.fcb, rec stored
|
|
;the r/w flag is still stacked. compare fcb values
|
|
;
|
|
PUSH DX
|
|
CALL CHK_INV_FCB
|
|
POP DX
|
|
JZ RANCLOSE
|
|
|
|
mov bx,modnum ;CHECK MODULE # FIRST
|
|
add bx,dx
|
|
mov al,ch ;b=seek mod#
|
|
;could be overflow at eof,
|
|
;producing module# of 90h
|
|
;or 10h, so compare all
|
|
;but fwf
|
|
sub al,[bx]
|
|
AND AL,3FH
|
|
JNZ RANCLOSE ;same?
|
|
|
|
mov bx,extnum
|
|
add bx,dx
|
|
MOV AL,[BX]
|
|
CMP AL,CL
|
|
JZ SEEKOK1 ;EXTENTS EQUAL
|
|
CALL COMPEXT
|
|
JNZ RANCLOSE
|
|
MOV [BX],CL ;EXTENTS IN SAME DIR FCB
|
|
;FCB(EXT) = CL
|
|
CALL GET_DIR_EXT
|
|
MOV CL,AL
|
|
CALL RESTORE_RC
|
|
CALL SET_RC
|
|
JMPS SEEKOK1
|
|
|
|
ranclose:
|
|
push cx
|
|
push dx ;save seek mod#,ext#, .fcb
|
|
call close ;current extent closed
|
|
pop dx
|
|
pop cx ;recall parameters and fill
|
|
mov bl,3 ;cannot close error #3
|
|
mov al,lret
|
|
inc al
|
|
jz badseek
|
|
MOV XDCNT,0FFFFH ;RESET XDCNT FOR MAKE
|
|
|
|
if MPM
|
|
|
|
MOV BYTE PTR SDCNT+1,0FFH
|
|
|
|
endif
|
|
|
|
mov bx,extnum
|
|
add bx,dx
|
|
mov [bx],cl ;fcb(extnum)=ext#
|
|
INC BX
|
|
INC BX
|
|
MOV AL,[BX] ;FCB(MODNUM)=MOD#
|
|
AND AL,40H ;COPY FILE WRITE FLAG
|
|
OR AL,CH
|
|
MOV [BX],AL
|
|
call open ;is the file present?
|
|
mov al,lret
|
|
inc al
|
|
jnz seekok ;open successful?
|
|
;cannot open file, read mode?
|
|
pop cx ;r/w flag to c (=0ffh if read)
|
|
push cx ;everyone expects this
|
|
;item stacked
|
|
mov bl,4 ;seek to unwritten extent #4
|
|
inc cl ;becomes 00 if read operation
|
|
jz badseek ;error if read operation
|
|
;write, make new extent
|
|
call make
|
|
mov bl,5 ;cannot create new extent #5
|
|
mov al,lret
|
|
inc al
|
|
jz badseek ;no dir space
|
|
;file make successful
|
|
|
|
if MPM
|
|
|
|
CALL FIX_OLIST_ITEM
|
|
|
|
endif
|
|
|
|
seekok:
|
|
MOV COMP_FCB_CKS,TRUE
|
|
SEEKOK1:
|
|
pop cx ;discard r/w flag
|
|
xor al,al
|
|
jmp staret ;with zero set
|
|
badseek:
|
|
;
|
|
;fcb no longer contains a valid fcb, mark
|
|
;with 1100$000b in modnum field so that it
|
|
;appears as overflow with file write flag set
|
|
;
|
|
push bx ;save error flag
|
|
MOV COMP_FCB_CKS,TRUE
|
|
CALL MAKE_FCB_INV
|
|
pop bx ;and drop through
|
|
seekerr:
|
|
pop cx ;discard r/w flag
|
|
MOV LRET,BL ;lret=#, nonzero
|
|
|
|
RET
|
|
;close ok
|
|
;ret
|
|
;
|
|
rdread:
|
|
;
|
|
;random disk read operation
|
|
;
|
|
mov cl,true ;marked as read operation
|
|
call rseek
|
|
JNZ RET19
|
|
JMP DISKREAD ;if seek successful
|
|
;
|
|
rdwrite:
|
|
;random disk write operation
|
|
mov cl,false ;marked as write operation
|
|
call rseek
|
|
JNZ RET19
|
|
JMP DISKWITE ;if seek successful
|
|
;
|
|
cmperr:
|
|
;compute random record position for getfilesize/setrandom
|
|
xchg bx,dx
|
|
add bx,dx
|
|
;dx=.buf(dptr) or .fcb(0),
|
|
;bx=.f(nxtrec/reccnt)
|
|
mov cl,[bx] ;pick up record no.
|
|
mov ch,0 ;cx = 0000 0000 ?rrr rrrr
|
|
mov bx,extnum
|
|
add bx,dx
|
|
mov ah,[bx]
|
|
mov al,0
|
|
shr ax,1
|
|
and ah,0fh
|
|
add cx,ax
|
|
;cx = 000? eeee errrr rrrr
|
|
mov bx,modnum
|
|
add bx,dx
|
|
mov al,[bx] ;AL = XXMM MMMM
|
|
AND AL,3FH
|
|
mov ah,16
|
|
mul ah ;AX = 0000 00MM MMMM 0000
|
|
add ch,al
|
|
;cx = mmmm eeee errr rrrr
|
|
MOV AL,0
|
|
ADC AL,AH ;AL = 0000 0?MM
|
|
RET19: ret
|
|
;
|
|
getfilesize:
|
|
;compute logical file size for current fcb
|
|
CALL GET_RRA ;ZERO RECEIVING RANREC FIELD
|
|
PUSH BX
|
|
XOR AL,AL
|
|
MOV [BX],AL
|
|
INC BX
|
|
MOV [BX],AL
|
|
INC BX
|
|
MOV [BX],AL
|
|
|
|
mov cl,extnum
|
|
call srch
|
|
getsize:
|
|
jz setsize
|
|
;current fcb addressed by dptr
|
|
call getdptra
|
|
mov dx,reccnt ;ready for compute size
|
|
call cmperr
|
|
;al=0000 000?,
|
|
;cx = mmmm eeee errr rrrr
|
|
;compare with memory, larger?
|
|
pop bx
|
|
push bx ;recall, replace .fcb(ranrec)
|
|
mov dl,al ;save cy
|
|
mov ax,cx
|
|
sub ax,[bx]
|
|
mov al,dl
|
|
sbb al,2[bx] ;carry if .fcb(ranrec) >
|
|
;directory
|
|
jb getnextsize ;for another try
|
|
;fcb is less or equal,
|
|
;fill from directory
|
|
mov 2[bx],dl
|
|
mov [bx],cx
|
|
getnextsize:
|
|
call srchn
|
|
MOV LRET,0
|
|
jmps getsize
|
|
setsize:
|
|
pop bx ;discard .fcb(ranrec)
|
|
ret
|
|
;
|
|
setrandom:
|
|
;set random record from the current fcb
|
|
MOV BX,DX
|
|
mov dx,nxtrec ;ready params for computesize
|
|
call cmperr ;dx=info, al=cy,
|
|
;cx=mmmm eeee errr rrrr
|
|
mov bx,ranrec
|
|
add bx,dx ;bx=.fcb(ranrec)
|
|
mov [bx],cx
|
|
mov 2[bx],al ;to ranrec
|
|
ret
|
|
;
|
|
TMP_SELECT: ;DL=DRIVE TO SELECT (0-F)
|
|
MOV BX,OFFSET SELDSK
|
|
MOV AL,[BX]
|
|
PUSH AX
|
|
MOV [BX],DL
|
|
CALL CUR_SELECT
|
|
POP AX
|
|
MOV SELDSK,AL
|
|
RET
|
|
;
|
|
XCURSELECT:
|
|
MOV RETURN_FFFF,TRUE
|
|
CALL CURSELECT
|
|
MOV RETURN_FFFF,FALSE
|
|
RET20A: RET
|
|
;
|
|
CURSELECT:
|
|
MOV AL,SELDSK
|
|
CMP AL,CURDSK
|
|
JE TEST_FF_DISK ;DON'T SELECT IF SELDSK = CURDSK
|
|
;
|
|
SELECT:
|
|
;select disk word ptr info for subsequent input or output ops
|
|
MOV DX,DLOG
|
|
CALL TEST_VECTOR
|
|
PUSH DX ;DL = 1 IF DRIVE LOGGED IN
|
|
;save it for test below,
|
|
;send to seldsk
|
|
call selectdisk
|
|
pop bx ;recall dlog vector
|
|
JNZ $+5
|
|
call selerror
|
|
;returns true if select ok
|
|
;is the disk logged in?
|
|
rcr bl,1
|
|
|
|
if MPM
|
|
|
|
JNB SELECT1
|
|
MOV DX,RLOG
|
|
CALL TEST_VECTOR
|
|
MOV REM_DRV,DL
|
|
RET
|
|
SELECT1:
|
|
|
|
endif
|
|
if CPM
|
|
|
|
JB RET20A ;rc
|
|
|
|
endif
|
|
;return if bit is set
|
|
;disk not logged in,
|
|
;set bit and initialize
|
|
mov cx,dlog
|
|
call setcdisk
|
|
mov dlog,bx ;dlog=set$cdisk(dlog)
|
|
|
|
if MPM
|
|
|
|
MOV AL,BYTE PTR CHKSIZ+1 ;IF HIGH ORDER BIT OF CHKSUM
|
|
RCL AL,1 ;VECTOR IS ZERO, THEN DRIVE
|
|
MOV AL,0
|
|
JB SELECT2 ;IS REMOVEABLE
|
|
MOV CX,RLOG
|
|
CALL SETCDISK
|
|
MOV RLOG,BX ;RLOG=SET_CDISK(RLOG)
|
|
MOV AL,1
|
|
SELECT2:
|
|
MOV REM_DRV,AL
|
|
|
|
endif
|
|
|
|
jmp initialize ;ret
|
|
|
|
;
|
|
TEST_FF_DISK:
|
|
INC AL
|
|
JNZ RET20A
|
|
JMP SEL_ERROR
|
|
|
|
;
|
|
SET_SELDSK:
|
|
MOV AL,LINFO
|
|
MOV SELDSK,AL
|
|
RET
|
|
|
|
;
|
|
RESELECTX:
|
|
MOV HIGH_EXT,0
|
|
JMP RESELECT1
|
|
;
|
|
reselect:
|
|
MOV CX,807FH ;CH = 80H, CL = 7FH
|
|
MOV BX,INFO
|
|
ADD BX,7
|
|
MOV AL,[BX] ;IF FCB(7) & 80H
|
|
AND AL,CH ;THEN XFCB_READ_ONLY = 80H
|
|
MOV XFCB_READ_ONLY,AL ;ELSE XFCB_READ_ONLY = 00H
|
|
AND [BX],CL ;FCB(7) = FCB(7) & 7FH
|
|
INC BX
|
|
MOV AL,[BX]
|
|
AND AL,CL ;FCB(8) = FCB(8) & 7FH
|
|
CMP AL,[BX]
|
|
MOV [BX],AL ;IF FCB(8) & 80H
|
|
MOV AL,60H ;THEN HIGH_EXT = 60H
|
|
JNZ RESELECT0
|
|
ADD BX,4 ;ELSE HIGH_EXT = FCB(12) & E0H
|
|
MOV AL,0E0H
|
|
AND AL,[BX]
|
|
RESELECT0:
|
|
MOV HIGH_EXT,AL
|
|
CALL CLR_EXT
|
|
CALL GETRCNTA
|
|
MOV AL,[BX] ;IF FCB(RCOUNT) & 80H
|
|
AND AL,CH ;THEN ACTUAL_RC = FCB(RCOUNT) & 7FH
|
|
JZ RESELECT1 ; FCB(RCOUNT) = 80H
|
|
MOV AL,[BX] ;ELSE ACTUAL_RC = 0
|
|
AND AL,CL
|
|
MOV [BX],CH
|
|
RESELECT1:
|
|
MOV ACTUAL_RC,AL
|
|
;check current fcb to see if reselection necessary
|
|
mov resel,true ;mark possible reselect
|
|
mov bx,info
|
|
mov al,[bx] ;drive select code
|
|
and al,00011111b ;non zero is auto drive select
|
|
dec al ;drive code normalized to
|
|
;0...30, or 255
|
|
mov linfo,al ;save drive code
|
|
cmp al,0FFH
|
|
JZ NOSELECT
|
|
;auto select function,
|
|
;save curdsk
|
|
MOV AL,SELDSK
|
|
mov olddsk,al ;olddsk=curdsk
|
|
mov al,[bx]
|
|
mov fcbdsk,al ;save drive code
|
|
and al,11100000b
|
|
mov [bx],al ;preserve hi bits
|
|
CALL SET_SELDSK
|
|
noselect:
|
|
CALL CURSELECT
|
|
;set user code
|
|
mov al,usrcode ;0...31
|
|
mov bx,info
|
|
or al,[bx]
|
|
mov [bx],al
|
|
ret20: ret
|
|
;
|
|
;
|
|
parsave33r:
|
|
call parsave33
|
|
jmp reselect
|
|
;
|
|
parsave36r:
|
|
call parsave36
|
|
jmp reselect
|
|
;
|
|
COPY_DMA_IN: ;COPY (CL) BYTES FROM USER'S
|
|
MOV SI,DMAAD ;DMA TO COMMON_DMA
|
|
MOV DI,OFFSET COMMON_DMA
|
|
PUSH DS
|
|
MOV DS,DMABASE
|
|
XOR CH,CH
|
|
REP MOVS AL,AL
|
|
POP DS
|
|
RET
|
|
;
|
|
COPY_DMA_OUT: ;COPY (CL) BYTES FROM COMMON_DMA
|
|
MOV DI,DMAAD ;TO USER'S DMA
|
|
MOV SI,OFFSET COMMON_DMA
|
|
PUSH ES
|
|
MOV ES,DMABASE
|
|
XOR CH,CH
|
|
REP MOVS AL,AL
|
|
POP ES
|
|
RET
|
|
;
|
|
CHK_PASSWORD:
|
|
CALL GET_DIR_MODE ;AL = DIR LBL DATA BYTE
|
|
AND AL,80H
|
|
JNZ CHK_PW ;BIT 0 ON => PASSWORDS ACTIVE
|
|
RET
|
|
;
|
|
GET_DIR_MODE:
|
|
MOV BX,DRVLBLA ;RETURN DIR LBL DATA BYTE IN AL
|
|
MOV AL,[BX]
|
|
RET
|
|
;
|
|
CHK_PW:
|
|
CALL GET_XFCB ;AL = XFCB PASSWORD MODE | 01H
|
|
JZ RET20 ;ZERO SET IF NO XFCB FOUND
|
|
DEC AL ;REMOVE LOW ORDER BIT
|
|
JZ RET20 ;ZERO SET IF PASSWORD MODE = 0
|
|
CALL CMP_PW ;COMPARE PASSWORDS
|
|
JZ RET20 ;ZERO SET IF PASSWORD OK
|
|
CHK_PW1: ;PASSWORD ERROR
|
|
MOV AL,7
|
|
JMP SET_ARET
|
|
;
|
|
CMP_PW: ;COMPARE PASSWORDS
|
|
;BX = .XFCB(12)
|
|
INC BX
|
|
MOV CH,[BX] ;FCB(13) = XFCB CHECKSUM
|
|
OR CH,CH
|
|
JNZ CMP_PW2 ;JUMP IF XFCB(13) ~= 0
|
|
MOV DX,BX ;SAVE BX
|
|
INC BX ;BECAUSE XFCB CHECKSUM IS ZERO
|
|
INC BX ;TEST FOR NULL PASSWORD
|
|
MOV CL,9 ;NULL PASSWORDS ARE ALL BLANKS AND/OR
|
|
CMP_PW1: ;ZEROS THAT SUM TO ZERO
|
|
INC BX ;ANY PASSWORD MATCHES A NULL PASSWORD
|
|
MOV AL,[BX]
|
|
DEC CL
|
|
JZ RET20 ;PASSWORD IS ALL BLANKS AND/OR ZEROS
|
|
OR AL,AL
|
|
JZ CMP_PW1
|
|
CMP AL,20H
|
|
JZ CMP_PW1
|
|
MOV BX,DX ;PASSWORD CONTAINS A VALUE OTHER
|
|
;THAN BLANK OR ZERO
|
|
|
|
CMP_PW2: ;BX = .XFCB(13)
|
|
LEA SI,10[BX]
|
|
LEA DX,3[BX] ;DX = .XFCB(16)
|
|
MOV BX,XDMAAD
|
|
MOV CL,8
|
|
CMP_PW3:
|
|
STD ;LODS DECREMENTS SI
|
|
LODS AL
|
|
XOR AL,CH ;EXCLUSIVE OR PASSWORD BYTE WITH CKS
|
|
CMP AL,[BX]
|
|
JNZ CMP_PW4 ;PASSWORD MISMATCH
|
|
INC BX
|
|
DEC CL
|
|
JNZ CMP_PW3
|
|
CLD
|
|
RET ;PASSWORD MATCHES
|
|
;
|
|
CMP_PW4:
|
|
CLD
|
|
MOV BX,OFFSET DF_PASSWORD ;COMPARE XFCB PASSWORD TO DEFAULT PW
|
|
MOV CL,8 ;BX = .DEFAULT PW, DX = .XFCB PASSWORD
|
|
JMP COMPARE
|
|
;
|
|
SET_PW: ;SET PASSWORD IN XFCB
|
|
PUSH BX ;SAVE .XFCB(12)
|
|
MOV CX,8 ;CH = 0, CL = 8
|
|
LEA SI,11[BX] ;SI = .XFCB(23)
|
|
MOV BX,XDMAAD
|
|
SET_PW0:
|
|
SUB AH,AH ;ZERO NULL PASSWORD FLAG
|
|
SET_PW1:
|
|
MOV AL,[BX]
|
|
MOV [SI],AL ;COPY PASSWORD CHAR TO XFCB
|
|
OR AL,AL ;IS PASSWORD CHAR ZERO?
|
|
JZ SET_PW2 ;YES
|
|
CMP AL,20H ;IS PASSWORD CHAR BLANK?
|
|
JZ SET_PW2 ;YES
|
|
INC AH ;PASSWORD IS NOT NULL
|
|
SET_PW2:
|
|
ADD CH,AL ;ADD PASSWORD CHAR TO XFCB CHKSUM
|
|
INC BX
|
|
DEC SI
|
|
DEC CL
|
|
JNZ SET_PW1
|
|
OR AH,CH ;IF (AH | CH) = 0 THEN PASSWORD IS NULL
|
|
POP BX
|
|
JNZ SET_PW3
|
|
MOV [BX],AH ;XFCB(EX) = 0, ZERO PASSWORD MODE
|
|
SET_PW3:
|
|
INC SI
|
|
MOV CL,8
|
|
SET_PW4:
|
|
MOV AL,[SI]
|
|
XOR AL,CH ;ENCRYPT PASSWORD CHARS IN XFCB
|
|
MOV [SI],AL
|
|
INC SI
|
|
DEC CL
|
|
JNZ SET_PW4
|
|
INC BX ;BX = .XFCB(13)
|
|
RET ;CH = XFCB PASWORD CHECKSUM
|
|
;
|
|
GET_XFCB: ;GET XFCB (SEARCH MODE)
|
|
SUB CH,CH
|
|
GET_XFCB0: ;GET NEXT XFCB (SEARCHN MODE)
|
|
MOV BX,INFO
|
|
MOV AL,[BX]
|
|
PUSH AX
|
|
OR B[BX],10H ;FCB(0) = FCB(0) | 10H
|
|
MOV CL,EXTNUM
|
|
CMP CH,0 ;TEST FOR MODE
|
|
JNZ GET_XFCB00
|
|
CALL SEARCH ;RETURNS WITH ZERO FLAG SET IF
|
|
JMPS GET_XFCB01 ;XFCB NOT FOUND
|
|
GET_XFCB00:
|
|
CALL SEARCHN ;RETURNS WITH ZERO FLAG SET IF
|
|
GET_XFCB01: ;XFCB NOT FOUND
|
|
MOV AL,0
|
|
MOV LRET,AL ;ZERO LRET
|
|
MOV BX,INFO
|
|
POP CX
|
|
MOV [BX],CL ;RESTORE FCB(0)
|
|
JNZ GET_XFCB1
|
|
RET ;XFCB NOT FOUND - AL = 0, ZFLAG SET
|
|
GET_XFCB1:
|
|
CALL GET_DPTRA
|
|
MOV DX,BX
|
|
ADD BX,EXTNUM
|
|
MOV AL,[BX]
|
|
AND AL,0E0H
|
|
OR AL,1 ;AL = XFCB(EXTNUM) & 0E0H + 1
|
|
RET ;XFCB FOUND, ZERO FLAG RESET
|
|
;
|
|
INIT_XFCB:
|
|
CALL SETCDR ;MAY HAVE EXTENDED THE DIRECTORY
|
|
MOV CX,1014H ;CH = 16, CL = 20
|
|
INIT_XFCB0: ;CH = FCB(0) LOGICAL OR MASK
|
|
;CL = ZERO COUNT
|
|
PUSH CX
|
|
CALL GETDPTRA ;DOES NOT USE CX
|
|
MOV SI,INFO ;XFCB(0) = FCB(0) | CH
|
|
MOV AL,[SI]
|
|
OR AL,CH
|
|
MOV [BX],AL
|
|
INC SI
|
|
INC BX
|
|
MOV CL,11
|
|
MOV DX,SI
|
|
CALL MOVE ;XFCB(1..11) = FCB(1..11)
|
|
MOV DX,SI ;DX = .FCB(12)
|
|
MOV BX,DI ;BX = .XFCB(12)
|
|
POP CX ;CL CONTAINS # OF REMAINING BYTES
|
|
SUB CH,CH ;OF XFCB TO ZERO
|
|
XOR AL,AL ;MOVE SETS DI TO ADDR OF NEXT CHAR
|
|
REP STOS AL
|
|
RET21: RET
|
|
;
|
|
CHK_XFCB_PASSWORD:
|
|
CALL GET_XFCB1 ;ACCESS XFCB IN DIRECTORY BUFFER
|
|
;BX = .XFCB(EX)
|
|
;AL = (XFCB(EXT) & E0H) | 1
|
|
DEC AL
|
|
CHK_XFCB_PASSWORD1:
|
|
JZ RET21
|
|
PUSH BX
|
|
CALL CMP_PW ;CHECK PASSWORD
|
|
POP BX
|
|
JZ RET21 ;RETURN WITH BX = .XFCB(EX)
|
|
JMP CHK_PW1
|
|
;
|
|
CHK_PWS:
|
|
CALL GET_DIR_MODE ;GET DIR LBL DATA BYTE
|
|
AND AL,80H
|
|
JZ RET21 ;RETURN IF PASSWORDS NOT ACTIVE
|
|
CALL GET_XFCB ;GET 1ST XFCB
|
|
CHK_PWS1:
|
|
JZ RET21 ;ZERO SET IF XFCB NOT FOUND
|
|
DEC AL
|
|
JZ $+7
|
|
CALL CMP_PW ;CHK PWS FOR XFCBS WITH NON-ZERO
|
|
;PASSWORD MODE
|
|
JNZ RET21 ;ZERO FLAG RESET => PASSWORD ERROR
|
|
MOV CH,1
|
|
CALL GET_XFCB0 ;GET NEXT XFCB
|
|
JMPS CHK_PWS1
|
|
;
|
|
STAMP1:
|
|
MOV CX,24
|
|
JMPS STAMP3
|
|
STAMP2:
|
|
MOV CX,28
|
|
STAMP3:
|
|
|
|
if MPM
|
|
|
|
MOV DX,OFFSET TOD
|
|
|
|
endif
|
|
if CPM
|
|
|
|
MOV DX,OFFSET STAMP
|
|
|
|
endif
|
|
|
|
CALL GETDPTRA
|
|
ADD BX,CX
|
|
MOV CL,4
|
|
JMP MOVE
|
|
;
|
|
COMPARE:
|
|
MOV CH,0
|
|
MOV SI,BX
|
|
MOV DI,DX
|
|
REP CMPS AL,AL
|
|
RET
|
|
|
|
|
|
if MPM
|
|
|
|
PACK_SDCNT:
|
|
;
|
|
;Packed_dcnt = dblk(low 15 bits) || dcnt (low 9 bits)
|
|
;
|
|
; if sdblk = 0 then dblk = shr(sdcnt,blkshf+2)
|
|
; else dblk = sdblk
|
|
; dcnt = sdcnt & (blkmsk || '11'b)
|
|
;
|
|
; packed_dcnt format (24 bits)
|
|
;
|
|
; 12345678 12345678 12345678
|
|
; 23456789 .......1 ........ sdcnt (low 9 bits)
|
|
; ........ 9abcdef. 12345678 sdblk (low 15 bits)
|
|
;
|
|
MOV BX,SDBLK
|
|
CMP BX,0 ;DOES SDBLK = 0?
|
|
JNE PACK_SDCNT1 ;NO
|
|
MOV BX,SDCNT
|
|
MOV CL,BLKSHF
|
|
ADD CL,2
|
|
SHR BX,CL
|
|
PACK_SDCNT1:
|
|
SHL BX,1 ;SHIFT DBLK LEFT 1
|
|
MOV DX,SDCNT
|
|
XOR AH,AH
|
|
MOV AL,BLKMSK
|
|
SHL AX,1
|
|
SHL AX,1
|
|
OR AL,11B
|
|
AND AX,DX ;DCNT = SDCNT & (BLKMSK || '11'B)
|
|
OR BL,AH
|
|
MOV PACKED_DCNT,AL
|
|
MOV WORD PTR PACKED_DCNT+1,BX
|
|
RET
|
|
;
|
|
;
|
|
;olist element = link(2) || atts(1) || dcnt (3) ||
|
|
; pdaddr(2) || opncnt(2)
|
|
;
|
|
; link = 0 -> end of list
|
|
;
|
|
; atts - 80 - open in locked mode
|
|
; 40 - open in unlocked mode
|
|
; 20 - open in read/only mode
|
|
; 10 - deleted item
|
|
; 0n - drive code (0-f)
|
|
;
|
|
; dcnt = packed sdcnt+sdblk
|
|
; pdaddr = process descriptor addr
|
|
; opncnt = # of open calls - # of close calls
|
|
; olist item freed by close when opncnt = 0
|
|
;
|
|
;llist element = link(2) || drive(1) || arecord(3)
|
|
; pdaddr(2) || .olist_item(2)
|
|
;
|
|
; link = 0 -> end of list
|
|
;
|
|
; drive - 0n - drive code (0-f)
|
|
;
|
|
; arecord = record number of locked record
|
|
; pdaddr = process descriptor addr
|
|
; .olist_item = address of file's olist item
|
|
;
|
|
SEARCH_OLIST:
|
|
mov bx,offset open_root! jmps search_listo
|
|
SEARCH_LLIST:
|
|
mov bx,offset lock_root! jmps search_listo
|
|
SEARCHN_LIST:
|
|
mov bx,cur_pos
|
|
search_listo:
|
|
mov prv_pos,bx
|
|
;
|
|
;search_olist, search_llist, searchn_list conventions
|
|
;
|
|
; CH = 0 -> return next item
|
|
; CH = 1 -> search for matching drive
|
|
; CH = 2 -> search for matching DCNT
|
|
; CH = 5 -> search for matching dcnt + pdaddr
|
|
;
|
|
; if found then z flag is set
|
|
; prv_pos -> previous list element
|
|
; cur_pos -> found list element
|
|
; else prv_pos -> list element to insert after
|
|
;
|
|
; olist and llist are maintained in drive order
|
|
;
|
|
srch_list1:
|
|
mov bx,[bx]! or bx,bx! jz srch_list3
|
|
or ch,ch! je srch_list6
|
|
inc bx! inc bx! mov cl,[bx]! and cl,0fh
|
|
mov dx,offset curdsk! mov si,dx
|
|
lods al! cmp al,cl! jne srch_list4
|
|
cmp ch,1! je srch_list5
|
|
mov cl,ch! push cx! push bx
|
|
inc dx! inc bx! call compare! pop bx
|
|
pop cx! jz srch_list5
|
|
srch_list2:
|
|
dec bx! dec bx
|
|
mov prv_pos,bx! jmp srch_list1
|
|
srch_list3:
|
|
or al,1! ret
|
|
srch_list4:
|
|
jae srch_list2
|
|
srch_list5:
|
|
pushf! dec bx! dec bx! popf
|
|
srch_list6:
|
|
mov cur_pos,bx! ret
|
|
|
|
DELETE_ITEM: ;BX -> item to be deleted
|
|
|
|
pushf! cli
|
|
mov si,[bx]! mov di,prv_pos! mov cur_pos,di
|
|
;prv_pos.link = delete_item.link
|
|
mov [di],si
|
|
;
|
|
mov si,free_root! mov free_root,bx
|
|
;delete_item.link = previous free_root
|
|
mov [bx],si! popf! ret
|
|
|
|
CREATE_ITEM: ;BX -> new item if successful
|
|
;Z flag set if no free items
|
|
|
|
mov bx,free_root! cmp bx,0! jnz $+3! ret
|
|
mov cur_pos,bx
|
|
;free_root = free_root.link
|
|
mov si,[bx]! mov free_root,si
|
|
;
|
|
mov si,prv_pos! mov di,[si]
|
|
;create_item.link = prv_pos.link
|
|
mov [bx],di
|
|
;prv_pos.link = .create_item
|
|
mov [si],bx! ret
|
|
|
|
SET_OLIST_ITEM: ;AL = attributes
|
|
;BX = olist entry address
|
|
|
|
inc bx! inc bx
|
|
mov si,offset curdsk! mov ah,[si]! or al,ah
|
|
lea dx,1[si]! mov [bx],al! inc bx
|
|
mov cl,5! call move
|
|
mov w[di],0
|
|
retl1:
|
|
ret
|
|
|
|
TST_OLIST:
|
|
|
|
mov chk_olist_flag,false! jmp chk_olist0
|
|
|
|
CHK_OLIST:
|
|
|
|
mov chk_olist_flag,true
|
|
chk_olist0:
|
|
mov dx,offset dcnt! mov bx,offset sdcnt
|
|
mov cl,4! call move
|
|
call pack_sdcnt! mov ch,3! call search_olist! jnz retl1
|
|
pop dx! test byte ptr 2[bx],80h! jz chk_olist05
|
|
push dx! push bx! call compare_pds! pop bx! pop dx! jz $+5
|
|
chk_olist05:
|
|
jmp openx06
|
|
push dx
|
|
test chk_olist_flag,true
|
|
jz retl1
|
|
call delete_item
|
|
inc_pdcnt:
|
|
mov al,pdcnt
|
|
chk_olist1:
|
|
add al,16! jz chk_olist1
|
|
mov pdcnt,al
|
|
ret
|
|
|
|
PR_TERM:
|
|
|
|
mov dx,pdaddr
|
|
mov bx,offset open_root! mov cur_pos,bx
|
|
pr_term1:
|
|
mov ch,0! push dx! call search_nlist! pop dx! jnz pr_term2
|
|
mov cx,6! push bx! call tst_tbl_lmt! pop bx! jnz pr_term1
|
|
call remove_locks! call delete_item
|
|
jmp pr_term1
|
|
pr_term2:
|
|
call func48
|
|
retl2:
|
|
ret
|
|
|
|
FLUSH_FILES:
|
|
|
|
test flushed,true! jnz retl2
|
|
mov flushed,true
|
|
|
|
FLUSH_FILE0:
|
|
|
|
mov bx,offset open_root! mov cur_pos,bx
|
|
flush_file1:
|
|
push ds! pop es
|
|
mov ch,1! call search_nlist! jnz retl2
|
|
push bx! call remove_locks! call delete_item! pop bx
|
|
mov bx,6[bx]! mov es,p_uda[bx]
|
|
test u_pd_cnt,1! jnz flush_file1
|
|
or u_pd_cnt,1! push ds! pop es
|
|
cmp bx,pdaddr! jnz flush_file1
|
|
call inc_pdcnt! jmps flush_file1
|
|
|
|
FREE_FILES:
|
|
;free_mode = 1 - remove curdsk files for process
|
|
; 0 - remove all files for process
|
|
mov dx,pdaddr! mov bx,offset open_root! mov cur_pos,bx
|
|
free_files1:
|
|
mov ch,free_mode
|
|
push dx! call search_nlist! pop dx! jnz retl25
|
|
mov cx,6! push bx! call tst_tbl_lmt! pop bx! jnz free_files1
|
|
cmp word ptr 3[bx],0ffffh! jnz free_files2
|
|
cmp byte ptr 5[bx],0ffh! jz free_files3
|
|
free_files2:
|
|
mov incr_pdcnt,true
|
|
free_files3:
|
|
call remove_locks! call delete_item
|
|
jmp free_files1
|
|
|
|
REMOVE_LOCKS: ;BX -> .olist_item
|
|
|
|
test byte ptr 2[bx],40h! jz retl25
|
|
push dx! push prv_pos
|
|
mov dx,bx! mov bx,offset lock_root! mov cur_pos,bx
|
|
remove_lock1:
|
|
mov ch,0! push dx! call searchn_list! pop dx
|
|
jnz remove_lock2
|
|
mov cx,8! push bx! call tst_tbl_lmt! pop bx! jnz remove_lock1
|
|
call delete_item
|
|
jmp remove_lock1
|
|
remove_lock2:
|
|
pop prv_pos! mov bx,dx! pop dx
|
|
retl25:
|
|
ret
|
|
|
|
TST_TBL_LMT:
|
|
|
|
add bx,cx
|
|
lea si,[bx]! cmp [si],dx! ret
|
|
|
|
CREATE_OLIST_ITEM:
|
|
|
|
mov ch,1! call search_olist
|
|
call create_item! mov al,attributes! call set_olist_item
|
|
ret
|
|
|
|
COUNT_OPENS:
|
|
|
|
mov open_cnt,0
|
|
mov dx,pdaddr! mov bx,offset open_root! mov cur_pos,bx
|
|
count_open1:
|
|
mov ch,0! push dx! call searchn_list! pop dx! jnz count_open2
|
|
mov cx,6! call tst_tbl_lmt! jnz count_open1
|
|
inc open_cnt! jmp count_open1
|
|
count_open2:
|
|
mov al,open_cnt! sub al,open_max
|
|
retl3:
|
|
ret
|
|
|
|
COUNT_LOCKS:
|
|
|
|
mov lock_cnt,0
|
|
mov dx,bx! mov bx,offset lock_root! mov cur_pos,bx
|
|
count_lock1:
|
|
mov ch,0! push dx! call searchn_list! pop dx! jnz retl3
|
|
mov cx,8! call tst_tbl_lmt! jnz count_lock1
|
|
inc lock_cnt! jmp count_lock1
|
|
|
|
CHECK_FREE:
|
|
mov dl,mult_cnt
|
|
CHECK_FREE0:
|
|
mov dh,0
|
|
mov bx,offset free_root! mov cur_pos,bx
|
|
check_free1:
|
|
mov ch,0! push dx! call searchn_list! pop dx! jnz check_free2
|
|
inc dh! cmp dh,dl! jb check_free1
|
|
retl4:
|
|
ret
|
|
check_free2:
|
|
pop bx! mov al,14! jmp sta_ret
|
|
|
|
LOCK:
|
|
mov cl,2! call copy_dma_in
|
|
call parsave36r! call check_fcb
|
|
test high_ext,80h! jz retl4
|
|
mov bx,xdmaad! mov bx,[bx]
|
|
mov al,curdsk! sub al,2[bx]! and al,0fh! jnz lock8
|
|
mov file_id,bx
|
|
test lock_unlock,true! jz lock1 ; jump if unlock
|
|
call count_locks
|
|
mov al,lock_cnt! add al,mult_cnt! jb lock0
|
|
cmp lock_max,al! jae lock05
|
|
lock0:
|
|
mov al,12! jmp sta_ret ; too many locks
|
|
lock05:
|
|
call check_free
|
|
lock1:
|
|
call save_rr! mov bx,offset lock9! push bx! mov ah,mult_cnt
|
|
lock2:
|
|
push ax! call get_lock_add
|
|
test lock_unlock,true! jz lock3 ; jump if unlock
|
|
call test_lock
|
|
lock3:
|
|
pop ax! dec ah! jz lock4
|
|
call incr_rr! jmps lock2
|
|
lock4:
|
|
call reset_rr! mov ah,mult_cnt
|
|
lock5:
|
|
push ax! call get_lock_add
|
|
test lock_unlock,true! jz lock6 ; jump if unlock
|
|
call set_lock! jmp lock7
|
|
lock6:
|
|
call free_lock
|
|
lock7:
|
|
pop ax! dec ah! jz retl5
|
|
call incr_rr! jmps lock5
|
|
lock8:
|
|
mov al,13! jmp sta_ret
|
|
lock9:
|
|
call reset_rr
|
|
retl5:
|
|
ret
|
|
|
|
GET_LOCKADD:
|
|
|
|
mov lock_sp,sp! mov lock_shell,true
|
|
call rseek
|
|
mov lock_shell,false
|
|
call getfcb
|
|
cmp aret,0! jnz lock_err
|
|
call index! call alloct
|
|
mov bx,1! jz lock_err
|
|
call atran
|
|
ret
|
|
|
|
LOCK_PERR:
|
|
|
|
mov lock_shell,false! mov sp,lock_sp
|
|
|
|
LOCK_ERR:
|
|
|
|
pop dx ; discard return address
|
|
pop cx ; CH = mult_cnt - # recs processed
|
|
mov al,mult_cnt! sub al,ch
|
|
mov cl,4! shl al,cl! or bh,al! mov aret,bx
|
|
retl6:
|
|
ret
|
|
|
|
TEST_LOCK:
|
|
|
|
call move_arecord
|
|
mov ch,3! call search_llist! jnz retl6
|
|
call compare_pds! jz retl6
|
|
mov bx,8! jmp lock_err
|
|
|
|
SET_LOCK:
|
|
|
|
call move_arecord
|
|
mov ch,1! call search_llist
|
|
pushf! cli
|
|
call create_item
|
|
xor al,al! call set_olist_item
|
|
mov dx,file_id! mov [di],dx
|
|
popf
|
|
retl7:
|
|
ret
|
|
|
|
FREE_LOCK:
|
|
|
|
call move_arecord
|
|
mov ch,5! call search_llist! jnz retl7
|
|
free_lock0:
|
|
call delete_item
|
|
mov ch,5! call searchn_list! jnz retl7
|
|
jmp free_lock0
|
|
|
|
COMPARE_PDS:
|
|
|
|
add bx,6! mov dx,offset pdaddr
|
|
mov cl,2! jmp compare
|
|
|
|
MOVE_ARECORD:
|
|
|
|
mov dx,offset arecord! mov bx,offset packed_dcnt
|
|
mov cl,3! jmp move
|
|
|
|
FIX_OLIST_ITEM:
|
|
|
|
mov si,offset xdcnt! mov di,offset sdcnt
|
|
mov cx,2
|
|
rep cmps ax,ax ; is xdcnt < sdcnt?
|
|
jae retl7 ; no
|
|
;yes - update olist entries
|
|
call swap! call sdcnt_eq_xdcnt
|
|
mov bx,offset open_root! mov cur_pos,bx
|
|
;find file's olist entries & change dcnt values
|
|
fix_ol1:
|
|
call swap! call pack_sdcnt! call swap
|
|
mov ch,3! call searchn_list! jnz retl8
|
|
;update olist entry with new dcnt value
|
|
push bx! call pack_sdcnt! pop bx
|
|
add bx,3! mov dx,offset packed_dcnt
|
|
mov cl,3! call move! jmp fix_ol1
|
|
|
|
REMOVE_DRIVE:
|
|
|
|
mov cl,curdsk! mov dx,1! shl dx,cl
|
|
not dx! and bx,dx
|
|
retl8:
|
|
ret
|
|
|
|
DISKRESET:
|
|
|
|
mov ntlog,0! mov set_ro_flag,0
|
|
mov bx,info
|
|
intrnl_disk_reset:
|
|
cmp open_root,0! jz retl8
|
|
mov al,curdsk! push ax! mov ch,0
|
|
dskrst1:
|
|
shr bx,1! jb dskrst3
|
|
dskrst2:
|
|
inc ch! cmp bx,0! jnz dskrst1
|
|
pop ax! mov curdsk,al
|
|
mov bx,ntlog! or tlog,bx
|
|
inc al! ret
|
|
dskrst3:
|
|
push cx! push bx! mov curdsk,ch! mov cl,ch
|
|
mov dx,tlog! call test_vector1! push dx
|
|
mov dx,rlog! call test_vector1! push dx
|
|
mov dx,rodsk! call test_vector1! pop bx
|
|
or bl,set_ro_flag! or bl,dl! pop dx! or bl,dl! mov check_disk,bl
|
|
mov bx,offset open_root! mov cur_pos,bx
|
|
dskrst4:
|
|
mov ch,1! call search_nlist! jnz dskrst6
|
|
test check_disk,true! jz dskrst5
|
|
push bx! call compare_pds! jz dskrst45
|
|
pop dx! xor al,al! jmp dskrst6
|
|
dskrst45:
|
|
mov cx,ntlog! mov al,curdsk! call set_cdisk1
|
|
mov ntlog,bx! pop bx! jmp dskrst4
|
|
dskrst5:
|
|
mov bx,info! call remove_drive! mov info,bx
|
|
or al,1
|
|
dskrst6:
|
|
pop bx! pop cx! jz $+5! jmp dskrst2
|
|
|
|
;error - olist item exists for another process
|
|
; on a removeable or read/only drive to be reset
|
|
; or any kind of drive if function is write protect disk
|
|
|
|
pop ax! mov curdsk,al
|
|
cmp error_mode,0ffh! je dskrst7
|
|
add ch,41h! mov denieddrv,ch
|
|
mov bx,dx! mov bx,6[bx]! mov al,p_cns[bx]! add al,30h
|
|
mov deniedcns,al
|
|
lea dx,p_name[bx]! mov bx,offset deniedprc
|
|
mov cl,8! call move
|
|
mov cx,offset deniedmsg
|
|
call xprint
|
|
dskrst7:
|
|
pop bx! mov aret,0ffffh! ret
|
|
|
|
endif
|