mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-26 01:44:21 +00:00
Upload
Digital Research
This commit is contained in:
904
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/01/FILE1.BDO
Normal file
904
MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/01/FILE1.BDO
Normal file
@@ -0,0 +1,904 @@
|
||||
|
||||
;*****************************************************************
|
||||
;*****************************************************************
|
||||
;** **
|
||||
;** b a s i c d i s k o p e r a t i n g s y s t e m **
|
||||
;** **
|
||||
;*****************************************************************
|
||||
;*****************************************************************
|
||||
;
|
||||
;
|
||||
; error message handlers
|
||||
;
|
||||
pererror:
|
||||
;report permanent error
|
||||
MOV BX,OFFSET PERMSG
|
||||
MOV CH,1
|
||||
JMPS GOERR
|
||||
|
||||
roderror:
|
||||
;report read/only disk error
|
||||
MOV BX,OFFSET RODMSG
|
||||
MOV CH,2
|
||||
JMPS GOERR
|
||||
|
||||
roferror:
|
||||
;report read/only file error
|
||||
MOV BX,OFFSET ROFMSG
|
||||
MOV CH,3
|
||||
JMPS GOERR
|
||||
|
||||
selerror:
|
||||
;report select error
|
||||
MOV BX,OFFSET SELMSG
|
||||
MOV CH,4
|
||||
|
||||
goerr:
|
||||
MOV CL,0FFH
|
||||
MOV ARET,CX ;SET ARET
|
||||
CMP ERROR_MODE,0FFH ;IF ERROR_MODE = 0FFH THEN
|
||||
JE RTN_PHY_ERRS ;RETURN PHYSICAL ERROR TO USER
|
||||
|
||||
JMPS REPORT_ERR ;REPORT ERROR TO USER
|
||||
|
||||
RTN_PHY_ERRS:
|
||||
|
||||
MOV BX,OFFSET RETURN_FFFF ;IF RETURN_FFFF THEN ARET = 0FFFFH
|
||||
TEST B[BX],TRUE
|
||||
JNZ $+5
|
||||
JMP GOBACK
|
||||
MOV B[BX],FALSE
|
||||
MOV ARET,0FFFFH
|
||||
JMP GOBACK
|
||||
|
||||
REPORT_ERR:
|
||||
|
||||
PUSH BX ;SAVE ERROR MESSAGE OFFSET
|
||||
CALL XCRLF ;PRINT CR,LF
|
||||
MOV AL,SELDSK
|
||||
ADD AL,'A'
|
||||
MOV DSKERR,AL ;SET D: FIELD
|
||||
MOV CX,OFFSET DSKMSG
|
||||
CALL XPRINT ;PRINT "Bdos Err On D:"
|
||||
POP CX
|
||||
CALL XPRINT ;PRINT ERROR MESSAGE
|
||||
|
||||
MOV AL,FX ;CONVERT FUNCTION TO CHARACTER
|
||||
MOV CH,30H
|
||||
MOV BX,OFFSET PRFX1
|
||||
CMP AL,100
|
||||
JC RPT_ERR1
|
||||
MOV B[BX],31H
|
||||
INC BX
|
||||
SUB AL,100
|
||||
RPT_ERR1:
|
||||
SUB AL,10
|
||||
JC RPT_ERR2
|
||||
INC CH
|
||||
JMPS RPT_ERR1
|
||||
RPT_ERR2:
|
||||
MOV [BX],CH
|
||||
INC BX
|
||||
ADD AL,3AH
|
||||
MOV [BX],AL
|
||||
INC BX
|
||||
MOV B[BX],20H
|
||||
MOV BX,OFFSET PR_FCB ;0 = MESSAGE DELIMITER
|
||||
MOV B[BX],0
|
||||
TEST RESEL,TRUE ;WAS RESELECT CALLED?
|
||||
JZ RPT_ERR3 ;NO - DON'T PRINT FCB
|
||||
MOV B[BX],20H ;REMOVE DELIMITER
|
||||
MOV DX,INFO
|
||||
INC DX
|
||||
MOV BX,OFFSET PR_FCB1
|
||||
MOV CL,8
|
||||
CALL MOVE ;MOVE FILE NAME TO MESSAGE
|
||||
MOV BX,DI
|
||||
MOV DX,SI
|
||||
MOV B[BX],'.' ;MOVE '.' TO MESSAGE
|
||||
INC BX
|
||||
MOV CL,3 ;MOVE FILE TYPE TO MESSAGE
|
||||
CALL MOVE
|
||||
RPT_ERR3:
|
||||
CALL XCRLF ;ADVANCE TO NEW LINE
|
||||
MOV CX,OFFSET PR_FX
|
||||
CALL XPRINT ;PRINT "Bdos Function : ### "
|
||||
; + "File: FFFFFFFF.TTT"
|
||||
CALL XCRLF
|
||||
CMP ERROR_MODE,0FEH ;IS ERROR MODE PRINT &
|
||||
; RETURN ERRORS?
|
||||
JE RPT_ERR4 ;YES
|
||||
MOV SI,RLR
|
||||
OR PFLAG[SI],PF_CTLC ;SET PROCESS ^C FLAG
|
||||
RPT_ERR4:
|
||||
JMP RTN_PHY_ERRS
|
||||
|
||||
;
|
||||
; local subroutines for bios interface
|
||||
;
|
||||
;
|
||||
;
|
||||
move:
|
||||
;move data length of length cl from source dx to
|
||||
;destination given by bx
|
||||
push cx
|
||||
mov ch,0
|
||||
mov si,dx
|
||||
mov di,bx
|
||||
rep movs al,al
|
||||
pop cx
|
||||
ret
|
||||
;
|
||||
;
|
||||
selectdisk:
|
||||
;select the disk drive given by curdsk, and fill
|
||||
;the base addresses curtrka - alloca, then fill
|
||||
;the values of the disk parameter block
|
||||
;
|
||||
MOV CURDSK,0FFH
|
||||
MOV CL,SELDSK ;current disk# to cl
|
||||
;lsb of dl = 0 if not yet
|
||||
;logged in
|
||||
call seldskf ;bx filled by call
|
||||
;bx = 0000 if error,
|
||||
;otherwise disk headers
|
||||
cmp bx,0
|
||||
jz ret4 ;rz
|
||||
mov dx,[bx]
|
||||
add bx,2
|
||||
mov cdrmaxa,bx
|
||||
add bx,2
|
||||
MOV DRVLBLA,BX
|
||||
ADD BX,4
|
||||
;dx still contains .tran
|
||||
xchg bx,dx
|
||||
mov tranv,bx ;.tran vector
|
||||
mov bx,offset buffa ;dx= source for move, bx=dest
|
||||
mov cl,addlist
|
||||
call move ;addlist filled
|
||||
;now fill the disk
|
||||
;parameter block
|
||||
mov dx,dpbaddr
|
||||
mov bx,offset sectpt ;bx is destination
|
||||
mov cl,dpblist
|
||||
call move ;data filled
|
||||
;set single/double map mode
|
||||
mov al,byte ptr maxall+1 ;largest allocation number
|
||||
MOV SINGLE,TRUE ;assume a=00
|
||||
or al,al
|
||||
jz retselect
|
||||
;high order of maxall not
|
||||
;zero, use double dm
|
||||
MOV SINGLE,FALSE
|
||||
retselect:
|
||||
MOV AL,SELDSK
|
||||
MOV CURDSK,AL
|
||||
INC AL
|
||||
ret4: ret ;select disk function ok
|
||||
;
|
||||
home:
|
||||
;move to home position, then offset to start of dir
|
||||
call homef
|
||||
;first directory pos. selected
|
||||
MOV DBLK,0
|
||||
ret
|
||||
;
|
||||
PASS_ARECORD:
|
||||
MOV DX,ARECORD
|
||||
MOV CH,BYTE PTR ARECORD+2
|
||||
RET
|
||||
;
|
||||
rdbuff:
|
||||
;read buffer and check if ok
|
||||
CALL PASS_ARECORD
|
||||
call readf ;current drive, track,....
|
||||
jmps diocomp ;check for i/o errors
|
||||
;
|
||||
wrbufflg:
|
||||
mov cl,wflag
|
||||
wrbuff:
|
||||
;write buffer and check condition
|
||||
;write type (wrtype) is in register cl
|
||||
;wrtype = 0 => normal write operation
|
||||
;wrtype = 1 => directory write operation
|
||||
;wrtype = 2 => start of new block
|
||||
CALL PASS_ARECORD
|
||||
OR CL,REM_DRV
|
||||
call writef ;current drive, track, ...
|
||||
diocomp: ;check for disk errors
|
||||
or al,al
|
||||
jz ret4 ;rz
|
||||
CMP AL,2
|
||||
JZ $+5
|
||||
jmp pererror
|
||||
JMP RODERROR
|
||||
;
|
||||
seekdir:
|
||||
|
||||
;seek the record containing the current dir entry
|
||||
|
||||
MOV DX,0FFFFH! XOR AH,AH ; MASK = FFFF
|
||||
MOV BX,DBLK! CMP BX,0! JZ SEEKDIR1
|
||||
INC DX! MOV DL,BLKMSK
|
||||
MOV CL,BLKSHF! MOV AL,BH
|
||||
|
||||
; AH+BX = SHL(DBLK,BLKSHF)
|
||||
|
||||
SHL BX,CL! SHL AX,CL
|
||||
|
||||
SEEKDIR1:
|
||||
|
||||
MOV SI,DCNT
|
||||
MOV CL,DSKSHF! SHR SI,CL
|
||||
|
||||
; ARECORD = SHL(DBLK,BLKSHF) + SHR(DCNT,DSKSHF) & MASK
|
||||
|
||||
AND DX,SI
|
||||
ADD BX,DX! ADC AH,0
|
||||
MOV ARECORD,BX! MOV BYTE PTR ARECORD+2,AH
|
||||
|
||||
seek:
|
||||
;seek the track given by arecord (actual record)
|
||||
|
||||
MOV AX,ARECORD ;COMPUTE TRACK/SECTOR
|
||||
XOR DX,DX
|
||||
MOV DL,BYTE PTR ARECORD+2
|
||||
DIV SECTPT ;DX=SECTOR, AX=TRACK
|
||||
PUSH DX! MOV CX,AX
|
||||
ADD CX,OFFSETV
|
||||
CALL SETTRKF ;SET BIOS/XIOS TRACK
|
||||
POP CX! MOV DX,TRANV
|
||||
CALL SECTRAN ;SET BIOS/XIOS SECTOR
|
||||
MOV CX,BX
|
||||
JMP SETSECF ;RET
|
||||
|
||||
;
|
||||
; utility functions for file access
|
||||
;
|
||||
dmposition:
|
||||
;compute disk map position for vrecord to bx
|
||||
mov bx,offset blkshf
|
||||
mov cl,[bx] ;shift count to cl
|
||||
mov al,vrecord ;current virtual record to a
|
||||
shr al,cl
|
||||
;a = shr(vrecord,blkshf) = vrecord/2**(sect/block)
|
||||
mov ch,al ;save it for later addition
|
||||
mov cl,7
|
||||
sub cl,[bx]
|
||||
mov al,extval ;extent value ani extmsk
|
||||
;
|
||||
;blkshf = 3,4,5,6,7
|
||||
;cl=4,3,2,1,0
|
||||
;shift is 4,3,2,1,0
|
||||
shl al,cl
|
||||
;arrive here with a = shl(ext and extmsk,7-blkshf)
|
||||
add al,ch ;add the previous
|
||||
;shr(vrecord,blkshf) value
|
||||
;al is one of the following
|
||||
;values, depending upon alloc
|
||||
;bks blkshf
|
||||
;1k 3 v/8 + extval * 16
|
||||
;2k 4 v/16+ extval * 8
|
||||
;4k 5 v/32+ extval * 4
|
||||
;8k 6 v/64+ extval * 2
|
||||
;16k 7 v/128+extval * 1
|
||||
ret ;with dm$position in a
|
||||
;
|
||||
GET_DMA: ;BX = .FCB(DSKMAP)
|
||||
MOV BX,INFO
|
||||
ADD BX,DSKMAP
|
||||
RET
|
||||
;
|
||||
getdm:
|
||||
;return disk map value from position given by cx
|
||||
CALL GET_DMA
|
||||
add bx,cx ;index by asingle byte value
|
||||
cmp single,0 ;single byte/map entry?
|
||||
jz getdmd ;get disk map single byte
|
||||
mov bl,[bx]
|
||||
mov bh,0
|
||||
ret ;with bx=00bb
|
||||
getdmd:
|
||||
add bx,cx ;bx=.fcb(dm+1*2)
|
||||
;return double precision value
|
||||
mov bx,[bx]
|
||||
ret
|
||||
;
|
||||
index:
|
||||
;compute disk block number from current fcb
|
||||
call dmposition ;0...15 in register al
|
||||
mov cl,al
|
||||
mov ch,0
|
||||
call getdm ;value to bx
|
||||
mov arecord,bx
|
||||
ret
|
||||
;
|
||||
alloct:
|
||||
;called following index to see if block allocated
|
||||
mov bx,arecord
|
||||
or bx,bx
|
||||
ret
|
||||
;
|
||||
atran:
|
||||
;compute actual record address, assuming index called
|
||||
mov cl,blkshf ;shift count to reg al
|
||||
mov bx,arecord
|
||||
XOR AH,AH
|
||||
MOV AL,BH
|
||||
shl bx,cl
|
||||
SHL AX,CL
|
||||
mov ablock,bx ;save shifted block #
|
||||
mov al,vrecord
|
||||
and al,blkmsk ;masked value in al
|
||||
or bl,al
|
||||
mov arecord,bx ;arecord=bx or
|
||||
;(vrecord and blkmsk)
|
||||
MOV BYTE PTR ARECORD+2,AH
|
||||
ret
|
||||
|
||||
;
|
||||
GET_ATTS:
|
||||
;GET INTERFACE ATTRIBUTES (F5' - F8') FROM FCB
|
||||
;RETURN ATTRIBUTES LEFT SHIFTED IN AL
|
||||
;ZERO INTERFACE ATTRIBUTE BITS IN FCB
|
||||
|
||||
MOV BX,INFO! ADD BX,5
|
||||
MOV CL,4! MOV DX,01111111B
|
||||
GET_ATTS_LOOP:
|
||||
MOV AL,[BX]! MOV CH,AL
|
||||
RCL AL,1! ADC DH,DH
|
||||
AND CH,DL! MOV [BX],CH
|
||||
INC BX! DEC CL! JNZ GET_ATTS_LOOP
|
||||
MOV AL,DH! MOV CL,4! SHL AL,CL! RET
|
||||
;
|
||||
GET_S1: ;GET CURRENT S1 FIELD TO AL
|
||||
|
||||
CALL GETEXTA! INC BX! MOV AL,[BX]! RET
|
||||
|
||||
;
|
||||
GET_RRA:
|
||||
;GET CURRENT RAN REC FIELD ADDRES TO BX
|
||||
|
||||
MOV BX,INFO! ADD BX,RANREC! RET
|
||||
;
|
||||
GET_RCNTA:
|
||||
;GET RECCNT ADDRES TO BX
|
||||
|
||||
MOV BX,INFO! ADD BX,RECCNT! RET
|
||||
;
|
||||
getexta:
|
||||
;get current extent field address to al
|
||||
mov bx,info
|
||||
add bx,extnum ;bx=.fcb(extnum)
|
||||
; mov al,[bx] ;*************** removed 7/14
|
||||
ret
|
||||
;
|
||||
gtfcba:
|
||||
;compute reccnt and nxtrec addresses for get/setfcb
|
||||
mov dx,reccnt
|
||||
add dx,info ;dx=.fcb(reccnt)
|
||||
mov bx,(nxtrec-reccnt)
|
||||
add bx,dx ;bx=.fcb(nxtrec)
|
||||
ret
|
||||
;
|
||||
getfcb:
|
||||
;set variables from currently addressed fcb
|
||||
call gtfcba ;addresses in dx, bx
|
||||
mov al,[bx]
|
||||
mov vrecord,al ;vrecord=fcb(nxtrec)
|
||||
xchg bx,dx
|
||||
mov al,[bx]
|
||||
mov rcount,al ;rcount=fcb(reccnt)
|
||||
call getexta ;bx=.fcb(extnum)
|
||||
mov al,extmsk ;extent mask to a
|
||||
and al,[bx] ;fcb(extnum) and extmsk
|
||||
mov extval,al
|
||||
ret
|
||||
;
|
||||
setfcb:
|
||||
;place values back into current fcb
|
||||
call gtfcba ;addresses to dx, bx
|
||||
mov al,seqio
|
||||
cmp al,02
|
||||
jnz setfc1
|
||||
xor al,al ;check ranfill
|
||||
setfc1:
|
||||
;=1 if sequential i/o
|
||||
add al,vrecord
|
||||
mov [bx],al ;fcb(nxtrec)=vrecord+seqio
|
||||
xchg bx,dx
|
||||
mov al,rcount
|
||||
mov [bx],al ;fcb(reccnt)=rcount
|
||||
ret
|
||||
;
|
||||
;
|
||||
cmpecs:
|
||||
;compute checksum for current directory buffer
|
||||
mov cx,recsiz ;size of directory buffer
|
||||
mov bx,buffa ;current directory buffer
|
||||
xor al,al ;clear checksum value
|
||||
cmpec0:
|
||||
add al,[bx]
|
||||
inc bx
|
||||
loop cmpec0
|
||||
ret ;with checksum in a
|
||||
;
|
||||
CHKSUM_FCB: ;COMPUTE CHECKSUM FOR FCB
|
||||
;ADD 1ST 12 BYTES OF FCB + CURDSK +
|
||||
; HIGH_EXT + XFCB_READONLY + BBH
|
||||
SUB AL,AL
|
||||
|
||||
if MPM
|
||||
|
||||
MOV BX,OFFSET PDCNT
|
||||
MOV CX,4
|
||||
|
||||
endif
|
||||
if CPM
|
||||
|
||||
MOV BX,OFFSET HIGH_EXT
|
||||
MOV CX,3
|
||||
|
||||
endif
|
||||
|
||||
CALL CMPEC0
|
||||
ADD AL,0BBH ;ADD BIAS
|
||||
MOV BX,INFO ;ADD 1ST 12 BYTES OF FCB
|
||||
MOV CX,12
|
||||
CALL CMPEC0
|
||||
INC BX ;SKIP EXTENT
|
||||
ADD AL,[BX] ;ADD S1
|
||||
ADD BX,3 ;SKIP MODNUM & RECCNT
|
||||
MOV CX,16 ;CHECKSUM DISK MAP
|
||||
CALL CMPEC0
|
||||
OR AL,AL ;ZERO FLAG SET IF CHEKSUM VALID
|
||||
RET
|
||||
;
|
||||
SET_CHKSUM_FCB:
|
||||
CALL CHKSUM_FCB ;COMPUTE FCB CHECKSUM
|
||||
JZ RET45 ;RETURN IF VALID
|
||||
MOV AH,AL ;SAVE CURRENT CHECKSUM VALUE
|
||||
CALL GETS1 ;GET S1 BYTE
|
||||
SUB AH,AL ;SUBTRACT FROM CHECKSUM VALUE
|
||||
NEG AH ;NEGATE RESULT
|
||||
MOV [BX],AH ;RESTORE S1
|
||||
RET45: RET
|
||||
;
|
||||
RESET_CHECKSUM_FCB:
|
||||
MOV COMP_FCB_CKS,0
|
||||
CALL CHKSUM_FCB ;COMPUTE FCB CHECKSUM
|
||||
JNZ RET45 ;RETURN IF INVALID
|
||||
CALL GETS1 ;INVALIDATE S1
|
||||
INC B[BX]
|
||||
RET
|
||||
;
|
||||
CHEK_FCB:
|
||||
CMP HIGH_EXT,01100000B ;DOES HIGH_EXT = 60H
|
||||
JNE CHKSUM_FCB ;NO
|
||||
MOV BX,INFO ;YES - SET FCB(0) TO ZERO
|
||||
MOV B[BX],0
|
||||
JMP CHKSUM_FCB
|
||||
;
|
||||
CHECK_FCB:
|
||||
|
||||
if MPM
|
||||
|
||||
MOV CHECK_FCB_RET,FALSE
|
||||
CHECK_FCB1:
|
||||
|
||||
endif
|
||||
|
||||
CALL CHEK_FCB ;COMPUTE FCB CHECKSUM
|
||||
JZ RET45 ;VALID IF ZERO
|
||||
|
||||
if MPM
|
||||
|
||||
AND AL,0FH ;IS MOD(CHKSUM,16) = 0 ?
|
||||
JNZ CHECK_FCB3 ;NO - INVALID CHECKSUM
|
||||
CMP PD_CNT,0 ;IS PDCNT = 0 ?
|
||||
JZ CHECK_FCB3 ;YES - INVALID CHECKSUM
|
||||
MOV BYTE PTR SDCNT+1,0FFH
|
||||
MOV DONT_CLOSE,TRUE
|
||||
CALL CLOSE1 ;ATTEMPT PARTIAL CLOSE
|
||||
MOV BX,OFFSET LRET
|
||||
INC B[BX]
|
||||
JZ CHECK_FCB3 ;PARTIAL CLOSE FAILED
|
||||
MOV B[BX],0 ;ZERO LRET
|
||||
CALL PACK_SDCNT ;LOOK FOR FILE IN LOCK LIST
|
||||
MOV CH,5
|
||||
CALL SEARCH_OLIST
|
||||
JNZ CHECK_FCB3 ;NOT FOUND - INVALID CHECKSUM
|
||||
RET ;FOUND - CHECKSUM OK
|
||||
CHECK_FCB3:
|
||||
|
||||
endif
|
||||
POP BX ;DISCARD RETURN ADDRESS
|
||||
|
||||
if MPM
|
||||
|
||||
CHECK_FCB4:
|
||||
TEST CHECK_FCB_RET,TRUE
|
||||
JNZ RET45
|
||||
|
||||
endif
|
||||
|
||||
MOV AL,10 ;10 = CHECKSUM ERROR
|
||||
JMP STA_RET
|
||||
|
||||
setcdisk:
|
||||
;set a "1" value in SELDSK position of cx
|
||||
MOV AL,SELDSK
|
||||
SET_CDISK1: ;SET A "1" VALUE IN AL POSITION OF CX
|
||||
push cx ;save input parameter
|
||||
MOV CL,AL
|
||||
mov bx,1 ;number to shift
|
||||
shl bx,cl ;bx = mask to integrate
|
||||
pop cx ;original mask
|
||||
or bx,cx ;bx = mask or rol(1,curdsk)
|
||||
ret
|
||||
;
|
||||
nowrite:
|
||||
;return true if dir checksum difference occurred
|
||||
MOV DX,RODSK
|
||||
TEST_VECTOR:
|
||||
MOV CL,SELDSK
|
||||
TEST_VECTOR1:
|
||||
SHR DX,CL
|
||||
AND DX,1
|
||||
ret ;non zero if nowrite
|
||||
;
|
||||
setro:
|
||||
;set current disk to read only
|
||||
mov cx,rodsk
|
||||
call setcdisk ;sets bit to 1
|
||||
mov rodsk,bx
|
||||
;high water mark in directory
|
||||
;goes to max
|
||||
mov dx,dirmax
|
||||
inc dx
|
||||
mov bx,cdrmaxa ;bx = .cdrmax
|
||||
mov [bx],dx ;cdrmax = dirmax
|
||||
ret
|
||||
;
|
||||
ckrodir:
|
||||
;check current directory element for read/only status
|
||||
call getdptra ;address of element
|
||||
;
|
||||
ckrofile:
|
||||
;check current buff(dptr) or fcb(0) for r/o status
|
||||
CALL RO_TEST
|
||||
jae ret5 ;rnc
|
||||
jmp roferror
|
||||
|
||||
RO_TEST:
|
||||
|
||||
ADD BX,ROFILE ;offset to r/o bit
|
||||
mov al,[bx]
|
||||
rcl al,1
|
||||
RET
|
||||
|
||||
checkwrite:
|
||||
;check for write protected disk
|
||||
call nowrite
|
||||
jz ret5 ;rz
|
||||
jmp roderror
|
||||
;
|
||||
getdptra:
|
||||
;compute the address of a directory element at
|
||||
;positon dptr in the buffer
|
||||
mov bx,buffa
|
||||
mov al,dptr
|
||||
addh:
|
||||
;bx = bx + al
|
||||
mov ah,0
|
||||
add bx,ax
|
||||
ret5: ret
|
||||
;
|
||||
;
|
||||
getmodnum:
|
||||
;compute the address of the module number
|
||||
;bring module number to accumulator
|
||||
;(high order bit is fwf (file write flag)
|
||||
mov bx,info
|
||||
add bx,modnum
|
||||
mov al,[bx]
|
||||
ret ;al=fcb(modnum)
|
||||
;
|
||||
clrmodnum:
|
||||
;clear the module number field for user open/make
|
||||
call getmodnum
|
||||
mov b[bx],0 ;fcb(modnum)=0
|
||||
ret
|
||||
;
|
||||
CLR_EXT:
|
||||
CALL GETEXTA
|
||||
AND B[BX],1FH
|
||||
RET
|
||||
;
|
||||
setfwf:
|
||||
call getmodnum ;bx=.fcb(modnum),
|
||||
;al=fcb(modnum)
|
||||
;set fwf(file write flag) to 1
|
||||
|
||||
or al,fwfmsk
|
||||
mov [bx],al ;fcb(modnum)=fcb(modnum) + 80h
|
||||
;also returns non zero
|
||||
;in accumulator
|
||||
ret
|
||||
;
|
||||
;
|
||||
compcdr:
|
||||
;return cy if cdrmax > dcnt
|
||||
mov dx,dcnt ;dx = directory counter
|
||||
mov bx,cdrmaxa ;bx=.cdrmax
|
||||
cmp dx,[bx]
|
||||
;condition dcnt - cdrmax
|
||||
;produces cy if cdrmax>dcnt
|
||||
ret6: ret
|
||||
;
|
||||
setcdr:
|
||||
;if not (cdrmax > dcnt) then cdrmax = dcnt+1
|
||||
call compcdr
|
||||
jb ret6 ;return if cdrmax > dcnt
|
||||
;otherwise, bx = .cdrmax+1,
|
||||
;dx = dcnt
|
||||
inc dx
|
||||
mov [bx],dx
|
||||
ret
|
||||
;
|
||||
subdh:
|
||||
;compute bx = dx - bx
|
||||
push dx
|
||||
sub dx,bx
|
||||
mov bx,dx
|
||||
pop dx
|
||||
ret
|
||||
;
|
||||
newchecksum:
|
||||
;drop through to compute new checksum
|
||||
mov cl,true
|
||||
checksum:
|
||||
;compute current checksum record and update the
|
||||
;directory element if cl=true, or check for = if not
|
||||
;drec < chksiz?
|
||||
MOV DX,ARECORD
|
||||
mov bx,chksiz
|
||||
AND BH,7FH ;REMOVE PERMANENT DRIVE BIT
|
||||
call subdh ;dx-bx
|
||||
jae ret6 ;skip checksum if past
|
||||
;checksum vector size
|
||||
;drec < chksiz, so continue
|
||||
push cx ;save init flag
|
||||
call cmpecs ;check sum value to al
|
||||
MOV BX,ARECORD ;value of ARECORD
|
||||
add bx,checka ;bx=.check(ARECORD)
|
||||
pop cx ;recall true or false to cl
|
||||
inc cl ;true produces zero flag
|
||||
jz initcs
|
||||
|
||||
if MPM
|
||||
|
||||
INC CL ;0FEH PRODUCES ZERO FLAG
|
||||
JZ TEST_DIR_CS
|
||||
|
||||
endif
|
||||
;not initializing, compare
|
||||
cmp al,[bx] ;compute$cs=check(ARECORD)?
|
||||
jz ret7 ;no message if ok
|
||||
;checksum error, are we beyond
|
||||
;the end of the disk?
|
||||
call compcdr
|
||||
jae ret7 ;no message if so
|
||||
|
||||
if MPM
|
||||
|
||||
CALL NOWRITE ;FLUSH FILES IF DRIVE IS NOT
|
||||
JNZ RET7 ;READ/ONLY
|
||||
CALL FLUSH_FILE0
|
||||
|
||||
endif
|
||||
|
||||
jmp setro ;read/only disk set
|
||||
|
||||
if MPM
|
||||
|
||||
TEST_DIR_CS:
|
||||
CMP AL,[BX] ;COMPUTE_CS=CHECK(ARECORD)
|
||||
JZ RET7
|
||||
JMP FLUSH_FILES
|
||||
|
||||
endif
|
||||
|
||||
initcs:
|
||||
;initializing the checksum
|
||||
mov [bx],al
|
||||
ret7: ret
|
||||
;
|
||||
;
|
||||
wrdir:
|
||||
;write the current directory entry, set checksum
|
||||
CALL CHECK_WRITE ;VERIFY DISK IS READ/WRITE
|
||||
call newchecksum ;initialize entry
|
||||
call setdir ;directory dma
|
||||
mov cl,1 ;indicates a write directory
|
||||
call wrbuff ;write the buffer
|
||||
jmp setdata ;to data dma address
|
||||
;ret
|
||||
;
|
||||
rddirbuf:
|
||||
;read a directory entry into the directory buffer
|
||||
call setdir ;directory dma
|
||||
call rdbuff ;directory record loaded
|
||||
; jmp setdata
|
||||
; ret
|
||||
;
|
||||
setdata:
|
||||
;set data dma address
|
||||
mov cx,dmabase
|
||||
call setdmbf ;set disk i/o base
|
||||
mov bx,offset dmaad
|
||||
jmps setdma ;to complete the call
|
||||
;
|
||||
setdir:
|
||||
;set directory dma address
|
||||
mov cx,ds
|
||||
call setdmbf ;set bios disk i/o base
|
||||
mov bx,offset buffa ;jmp setdma to complete call
|
||||
;
|
||||
setdma:
|
||||
;bx=.dma address to set (i.e., buffa or dmaad)
|
||||
mov cx,[bx] ;parameter ready
|
||||
jmp setdmf
|
||||
;
|
||||
;
|
||||
dirtouser:
|
||||
;copy the directory entry to the user buffer
|
||||
;after call to search or searchn by user code
|
||||
mov dx,buffa ;source is directory buffer
|
||||
mov bx,dmaad ;destination is user dma addr.
|
||||
mov cl,recsiz ;copy entire record
|
||||
push es ;move to user segment
|
||||
mov es,parametersegment
|
||||
call move
|
||||
pop es
|
||||
ret
|
||||
|
||||
MAKE_FCB_INV:
|
||||
;FLAG FCB AS INVALID
|
||||
|
||||
CALL SETFWF ;RESET FCB WRITE FLAG
|
||||
INC BX
|
||||
INC BX
|
||||
MOV W[BX],0FFFFH
|
||||
RET
|
||||
|
||||
CHK_INV_FCB:
|
||||
;CHECK FOR INVALID FCB
|
||||
|
||||
CALL GETDMA
|
||||
JMPS TEST_FFFF
|
||||
|
||||
TST_INV_FCB:
|
||||
;TEST FOR INVALID FCB
|
||||
|
||||
CALL CHK_INV_FCB
|
||||
JNZ RET8
|
||||
POP BX
|
||||
MOV AL,9
|
||||
JMP STA_RET
|
||||
|
||||
endofdir:
|
||||
;return zero flag if at end of director, non zero
|
||||
;if not at end (end of dir if dcnt = 0ffffh)
|
||||
mov bx,offset dcnt
|
||||
TEST_FFFF:
|
||||
CMP W[BX],0FFFFH
|
||||
|
||||
; mov al,[bx] ;may be 0ffh
|
||||
; inc bx
|
||||
; cmp al,[bx] ;low(dcnt) = high(dcnt)?
|
||||
; jnz ret8 ;return non zero if different
|
||||
; ;high and low the same,= 0ffh?
|
||||
; inc al ;0ffh becomes 00 if so
|
||||
|
||||
ret8: ret
|
||||
;
|
||||
setenddir:
|
||||
;set dcnt to the end of the directory
|
||||
MOV DCNT,ENDDIR
|
||||
ret
|
||||
;
|
||||
rddir:
|
||||
;read next directory entry, with cl=true if initializing
|
||||
mov dx,dirmax ;in preparation for subtract
|
||||
mov bx,dcnt
|
||||
inc bx
|
||||
mov dcnt,bx ;dcnt=dcnt+1
|
||||
;continue while dirmax >= dcnt
|
||||
;(dirmax-dcnt no cy)
|
||||
call subdh ;dx-bx
|
||||
jae rddir0
|
||||
;yes, set dcnt to end
|
||||
;of directory
|
||||
jmps setenddir
|
||||
; ret
|
||||
rddir0:
|
||||
;not at end of directory, seek next element
|
||||
;cl=initialization flag
|
||||
mov al,ldcnt
|
||||
and al,dskmsk ;low(dcnt) and dskmsk
|
||||
push cx
|
||||
mov cl,fcbshf ;to multiply by fcb size
|
||||
shl al,cl
|
||||
pop cx
|
||||
;a = (low(dcnt) and dskmsk)
|
||||
;shl fcbshf
|
||||
mov dptr,al ;ready for next dir operation
|
||||
or al,al
|
||||
jnz ret71 ;return if not a new record
|
||||
push cx ;save initialization flag cl
|
||||
call seekdir ;seek proper record
|
||||
call rddirbuf ;read the directory record
|
||||
pop cx ;recall initialization flag
|
||||
jmp checksum ;checksum the directory elt
|
||||
;ret
|
||||
;
|
||||
;
|
||||
getallocbit:
|
||||
;given allocation vector
|
||||
;position on cx, return byte
|
||||
;containing cx shifted so that the least significant
|
||||
;bit is in the low order accumulator position. bx is
|
||||
;the address of the byte for
|
||||
;possible replacement in
|
||||
;memory upon return, and dh contains the number of shifts
|
||||
;required to place the returned value back into position
|
||||
;
|
||||
mov dx,cx
|
||||
and cl,111b
|
||||
inc cl
|
||||
mov ch,cl
|
||||
;ch and cl both contain the
|
||||
;number of bit positions to
|
||||
;shift
|
||||
mov cl,3
|
||||
shr dx,cl ;shift bit address right 3 for byte address
|
||||
;dx shr 3 to dx
|
||||
mov bx,alloca ;base addr. of alloc. vector
|
||||
add bx,dx
|
||||
;byte to a, hl =
|
||||
mov al,[bx] ;.alloc(cx shr 3)
|
||||
;now move the bit to the
|
||||
;low order position of al
|
||||
mov cl,ch
|
||||
rol al,cl
|
||||
mov dx,cx
|
||||
ret71: ret
|
||||
;
|
||||
;
|
||||
setallocbit:
|
||||
;cx is the bit position of alloc to set or reset. the
|
||||
;value of the bit is in register dl.
|
||||
push dx
|
||||
call getallocbit ;shifted val al,count in dl
|
||||
and al,11111110b ;mask low bit to zero
|
||||
;(may be set)
|
||||
pop cx
|
||||
or al,cl ;low bit of cl masked into al
|
||||
; jmp rotr
|
||||
; ret
|
||||
rotr:
|
||||
;byte value from alloc is in register al, with shift count
|
||||
;in register ch (to place bit back into position), and
|
||||
;target alloc position in registers bx, rotate and replace
|
||||
;
|
||||
push cx
|
||||
mov cl,dh
|
||||
ror al,cl
|
||||
mov [bx],al
|
||||
pop cx
|
||||
ret
|
||||
;
|
||||
;************* end bdos filesystem part 1 **************
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user