Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

4084 lines
72 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; BASIC DISK OPERATING SYSTEM OF CP/M 86
;
; 1983.8.16.
;
; EQUATIONS OF FUNCTION
;
CLIST EQU 5 ;LIST OUT
CRTVNO EQU 12 ;RETURN VERION NUMBER
CREADS EQU 20 ;READ SEQUENTIAL
CSTDMA EQU 26 ;SET DMA OFFSET
CSTDMS EQU 51 ;SET DMA SEGMENT
CGTMXM EQU 53 ;GET MAXIMUM MEMORY
CGTAMX EQU 54 ;GET ABSOLUTE MAXIMUM MEOMRY
CALMEM EQU 55 ;ALLOCATE MEMORY
CALAME EQU 56 ;ALLOCATE ABSOLUTE MEMORY
;
; EQUATIONS OF DATA
;
BS EQU 8 ;BACK SPACE
HT EQU 9 ;HORIZONTAL TAB
LF EQU 0AH ;LINE FEED
CR EQU 0DH ;CARRIAGE RETURN
ITBDOS EQU 0E0H ;BDOS INTERRUPT VECTOR
DELCOD EQU 0E5H ;DELETED FILE DIRECTORY CODE
;
; EQUATIONS OF DATA
;
COMBUF EQU 9 ;COMMAND BUFFER OF CCP
MDSUBE EQU 0805H ;SUBMIT MODE
;
; EQUATIONS OF BIOS VECTOR
;
VBIOS EQU 2500H ;BIOS JUMP VECTOR TOP
VINIT EQU VBIOS+00H ;INITIALIZE COLD START
VWBOOT EQU VBIOS+03H ;WARM START
VCONST EQU VBIOS+06H ;CONSOLE STATUS
VCONIN EQU VBIOS+09H ;CONSOLE INPUT
VCONOT EQU VBIOS+0CH ;CONSOLE OUTPUT
VLIST EQU VBIOS+0FH ;LIST OUT
VPUNCH EQU VBIOS+12H ;PUNCH OUT
VREADR EQU VBIOS+15H ;READER IN
VHOME EQU VBIOS+18H ;HOME
VSLDSK EQU VBIOS+1BH ;SELECT DISK
VSTTRK EQU VBIOS+1EH ;SET TRACK
VSTSEC EQU VBIOS+21H ;SET SECTOR
VSTDMA EQU VBIOS+24H ;SET DMA OFFSET
VDREAD EQU VBIOS+27H ;READ ONE SECTOR
VDWRIT EQU VBIOS+2AH ;WRITE ONE SECTOR
VSCTRN EQU VBIOS+30H ;SECTOR TRANSLATE
VSTDMS EQU VBIOS+33H ;SET DMA SEGMENT
VGTMRT EQU VBIOS+36H ;GET MEMORY REGION TABLE
VGTIOB EQU VBIOS+39H ;GET I/O BYTE
VSTIOB EQU VBIOS+3CH ;SET I/ BYTE
;
;
CSEG
ORG 0
TOP: ;DUMMY FOR TAGGED LABEL
;
ORG 0A20H
;
; PATCH AREA
;
; FOR LOAD PROGRAM
;
MLOADK: ;OK END
MOV INSTOF,AX ;RESTORE ENTRY STACK & END FOR LOAD PROGRAM
POP ES
RET
;
ORG 0A30H
;
MLOADQ: ;ERROR END OF LOAD PROGRAM
MOV AX,FCBSEG
MOV INDSEG,AX
MOV OTPARA,-1
JMP MLOADE
;
ORG 0A50H
;
; FOR BDOS BODY
; CHECK BDOS FUNCTION CODE RANGE
;
BDOSBC:
JC BDOSBI ;IN RANGE
MOV OTPARA,-1 ;OVER END
RET
;
BDOSBI: ;IN RANGE
JMP BDOSBS
;
;
ORG 0A60H
DB '12 january 82'
;
ORG 0A80H
;
; BDOS FUNCTION INDEX
;
IXMAIN:
DW MSYRST ; 0 SYSTEM RESET
DW MCONIN ; 1 CONSOLE INPUT
DW CONOUT ; 2 CONSOLE OUTPUT
DW MREDER ; 3 READER INPUT
DW VPUNCH ; 4 PUNCHER UTPUT
DW BLIST ; 5 LIST OUTPUT
DW MDCNIO ; 6 DIRECT CONSOLE I/O
DW MGTIOB ; 7 GET I/O BYTE
DW MSTIOB ; 8 SET I/O BYTE
DW MBUFPR ; 9 PRINT STRING
DW MRDCBF ;10 READ CONSOLE BUFFER
DW MCONST ;11 CONSOLE STATUS
DW MRTVNO ;12 RETURN VERSION NUMBER
DW MRSDSY ;13 RESET DISK SYSTEM
DW MSELDK ;14 SELECT DISK
DW MOPEN ;15 OPEN FILE
DW MCLOSE ;16 CLOSE FILE
DW MSRCHF ;17 SEARCH FOR FIRST
DW MSRCHN ;18 SEARCH FOR NEXT
DW MDELET ;19 DELETE FILE
DW MREADS ;20 READ SEQUENTIAL
DW MWRITS ;21 WRITE SEQUENTIAL
DW MMAKE ;22 MAKE FILE
DW MRENAM ;23 RENAME FILE
DW MRTLIV ;24 RETURN LOGIN VECTOR
DW MRTCDK ;25 RETURN CURRENT DISK
DW MSTDMO ;26 SET DMA OFFSET
DW MGTALM ;27 GET ALLOCATION MAP ADDRESS
DW MWPDSK ;28 WRITE PROTECT DISK
DW MGTROV ;29 GET READ/ONLY VECTOR
DW MSTFAT ;30 SET FILE ATTRIBUTE
DW MGDPBA ;31 GET DISK PARAMETER BLOCK ADDRESS
DW MSTUCD ;32 SET/GET USER CODE
DW MREADR ;33 READ RANDOM
DW MWRITR ;34 WRITE RANDOM
DW MCMPFS ;35 COMPUTE FILE SIZE
DW MSTRRC ;36 SET RANDOM RECORD
DW MRSTDV ;37 RESET DRIVE
DW NOPROC ;38 ACCESS DRIVE
DW NOPROC ;39 FREE DRIVE
DW MWRITZ ;40 WRITE RANDOM WITH ZERO FILL
DW MCHAIN ;47 CHAIN TO PROGRAM
DW MFLUSH ;48 FLUSH BUFFERS
DW MGTSAD ;49 GET SYSTEM ADDRESS
DW MDBIOS ;50 DIRECT BIOS CALL
DW MSTDMS ;51 SET DMA SEGMENT
DW MGTDMS ;52 GET DMA ADDRESS
DW MGTMXM ;53 GET MAXIMUM MEMORY
DW MGTAMX ;54 GET ABSOLUTE MAXIMUM MEMORY
DW MALMEM ;55 ALLOCATE MEMORY SEGMENT
DW MALAME ;56 ALLOCATE ABSOLUTE MEMORY SEGMENT
DW MFRMEM ;57 FREE SPECIFIED MEMORY SEGMENT
DW MFRALM ;58 FREE ALL MEMORY
DW MLOADP ;59 PROGRAM LOAD
;
; 12:RETURN VERSION NUMBER
;
MRTVNO:
MOV AL,022H ;2.2 IS VERSION NUMBER
JMP BTPRST ;H=0 SIMPLE CP/M
;
; 49:GET SYSTEM ADDRESS
;
MGTSAD:
MOV BX,OFFSET DMAADD ;SYSTEM DATA AREA TOP
JMP WDPRST
;
; BDOS NORMAL TOP
;
ORG 0B00H
;
; USER ID CODE OF BDOS
;
DB 1 ;OEM CODE
DB 10 ;VERSION NUMBER
DB 0
DB 0,0,0 ;USER ID
;
; BDOS ENTRY
;
BDOSEN:
PUSH DS
MOV AX,CS
MOV DS,AX
POP INDSEG ;SAVE ENTRY DATA SEGMENT
CMP CL,CLIST
JZ BDOSEC
CMP CL,CRTVNO+1
JC BDOSES ;SIMPLE BDOS CALL
BDOSEC: ;COMPLICATED I/O FUNCTION
MOV MDCONF,-1 ;SET COMPLICATED I/O MODE
BDOSES:
MOV INSTSG,SS
MOV INSTOF,SP ;SAVE ENTRY STACK
CMP FLINSD,1
JZ BDOSEI ;FROM INSIDE
MOV AX,CS
MOV SS,AX
MOV SP,OFFSET STACK ;SET SYSTEM STACK
BDOSEI:
MOV BX,INSTOF
MOV ES,INSTSG
MOV BX,ES:4[BX]
AND BX,200H ;GET INTERRUPT FALG
JZ $+3 ;DI
STI ;EI
MOV AX,DS
PUSH BP
PUSH DI
PUSH SI
PUSH CS
POP ES
MOV CURSEG,ES ;SAVE CURRENT SEGMENT
CALL BDOSB ;CALL BDOS BODY
POP SI
POP DI
POP BP
MOV ES,CURSEG
CLI
MOV SS,INSTSG ;RESTORE STACK
MOV SP,INSTOF
MOV MDCONF,0 ;CLEAR COMPLICATED I/O MODE
MOV DS,INDSEG
IRET
;
; BDOS BODY
;
BDOSB:
MOV INPARA,DX
MOV INPARB,DL
XOR AX,AX
MOV OTPARA,AX ;CLEAR OUTPUT PARAMETER
MOV AFWFCB,AL
MOV ENTTYP,AL
MOV FLOMOD,AL
MOV BX,OFFSET ENDPRC
PUSH BX ;SET RETURN ADDRESS
CMP CL,41
JC BDOSBS ;0 TO 40
SUB CL,6
CMP CL,60-6 ;47 TO 59
JMP BDOSBC ;CHECK OVER
;
BDOSBS:
MOV BL,CL
MOV BH,0
MOV CL,DL ;SET BYTE PARAMETER
ADD BX,BX
JMP WORD PTR IXMAIN[BX] ;TO EACH ROUTINE
;
; ERROR ROUTINES
;
; BAD SECTOR ERROR
;
EBADSC:
MOV BX,OFFSET CBADSC ;BAD SECTOR
CALL ERPROC
CMP AL,'C'-40H
JNZ STWFCE ;CONTINUE
JMPS EROFIE ;ABORT
;
; SELECT ERROR
;
ESELCT:
MOV BX,OFFSET CSELCT
JMPS EROFIS
;
; R/O DISK
;
ERODSK:
MOV BX,OFFSET CRODSK
JMPS EROFIS
;
; R/O FILE
;
EROFIL:
MOV BX,OFFSET CROFIL
EROFIS:
CALL ERPROC ;OUT COMMENT & WAIT RESPONSE
EROFIE:
JMP MSYRSA
;
; ERROR TRAP PROCESS
; INPUT
; BX:COMMENT POINT
;
ERPROC:
PUSH BX ;SAVE EACH COMMNET POINT
CALL CRLF
MOV AL,CURDSK
ADD AL,'A'
MOV CERRDK,AL ;SET DRIVE NAME
MOV CX,OFFSET CERROR
CALL BUFPRN ;BDOS ERROR ON X:
POP CX
CALL BUFPRN ;OUT EACH COMMENT
JMP CONINC ;RESPONSE WAIT
;
; SET INPUT DATA TO WORK FCB OR MCB
; INPUT
; CL:COPY COUNT
;
STWFCB:
PUSH DS
PUSH AX
PUSH CX
MOV AFWFCB,0FFH
MOV CNFCBC,CL ;SAVE COPY LENGTH
XOR CH,CH
MOV SI,INPARA ;OFFSET OF INPUT PARAMETER
MOV PTUFCB,SI
MOV DI,OFFSET WKFCB ;OFFSET OF WORK
MOV INPARA,DI
MOV DS,INDSEG ;SEGMENT OF INPUT PARAMETER
CLD
REP MOVSB ;GET DATA
POP CX
POP AX
POP DS
STWFCE:
RET
;
; SET SEQUENTIAL FCB
;
STWFCS:
PUSH CX
MOV CL,33 ;SEQUENTIAL FCB LENGTH IS 33
JMPS STWFCC
;
; SET RANDOM FCB
;
STWFCR:
PUSH CX
MOV CL,36 ;RANDOM FCB LENGTH IS 36
STWFCC:
CALL STWFCB
POP CX
RET
;
; RESTORE FCB DATA
;
RSTFCB:
PUSH ES
PUSH AX
PUSH CX
MOV CL,CNFCBC ;GET LENGTH
XOR CH,CH
MOV ES,INDSEG ;SEGMENT OF INPUT PARAMETER
MOV SI,OFFSET WKFCB
MOV DI,PTUFCB ;OFFSET OF ORIGINAL
MOV INPARA,DI
CLD
REP MOVSB ;RESTORE FCB DATA
POP CX
POP AX
POP ES
RET
;
; READ BY FAR ADDRESS FCB
;
READFR:
MOV CL,CREADS
MOV DX,UFCBOF ;USER FCB OFFSET
MOV DS,FCBSEG ;USER FCB SEGMENT
CALL BDOSIS ;READ SEQUENTIAL
MOV AX,CS
MOV DS,AX ;RESTORE SEGMENT
RET
;
; BDOS CALL FROM INSIDE OF BDOS
;
; MUST BE SAVE STACK SAVE AREA
; & CLEAR INSIDE FLAG AT END ???
;
BDOSIS:
MOV CS:FLINSD,1 ;SET INSIDE FLAG
INT ITBDOS
RET
;
; INTERNAL BDOS CALL FOR MEMORY MANAGEMENT
; INPUT
; CL:FUNCTION CODE
;
BDOSMM:
PUSH BX
MOV DX,OFFSET SYSMCB
CALL BDOSIS
POP BX
RET
;
; MEMORY MANAGEMENT UTILITY
;
; COMPARE MEMORY REQUEST BETWEEN MAX-MIN
; INPUT
; SI:GROUP DESCRIPTOR TOP
; DI:GROUP DESCRIPTOR TOP
; OUTPUT
; SI:SMALLER GD
; DI:LARGER GD
;
CMPMRQ:
PUSH AX
PUSH BX
MOV BX,7[SI]
SUB BX,5[SI] ;GET MAX-MIN
MOV AX,7[DI]
SUB AX,5[DI]
CMP BX,AX
JBE $+4 ;(DI) > (SI)
XCHG SI,DI
POP BX
POP AX
RET
;
; ALLOCATE MEMORY FOR LOAD PROGRAM
; OUTPUT
; AL:0 OK -1 CANNOT ALLOCATE
;
ALMEMR:
SUB BX,BX ;CLEAR MIN SIZE
SUB DX,DX ;CLEAR MAX SIZE
MOV FMODEL,0FFH ;SET 8080 MODEL FLAG
MOV CX,8 ;COUNT OF GROUP DESCRIPTOR
MOV SI,OFFSET BFGRDC ;BUFFER TOP
ALMEML: ;LOOP OF ONE GROUP DESCRIPTOR
CMP BYTE PTR [SI],0
JZ ALMEMN ;NOT ACTIVE DESCRIPTOR
CMP BYTE PTR [SI],2
JNZ ALMEMD ;NOT DATA GROUP
MOV FMODEL,0 ;DATA GROUP SO NOT 8080 MODEL
ALMEMD:
CMP WORD PTR 3[SI],0
JZ ALMEMG ;RELOCATABLE
MOV AX,3[SI] ;ABSOLUTE
MOV SYSMCB,AX ;SET ABSOLUTE BASE
CMP WORD PTR 7[SI],0
MOV AX,5[SI] ;MIN
JZ $+5 ;NO MAX SO DO BY MIN
MOV AX,7[SI] ;WITH MAX SO DO BY MAX
MOV SYSMCB+2,AX ;SET LENGTH
PUSH CX
MOV CL,CALAME
PUSH DX
CALL BDOSMM ;ALLOCATE ABSOLUTE MEMORY SEGMENT
POP DX
POP CX
CMP OTPARB,0
JZ ALMEMN ;OK ALLOCATED
PUSH CX ;NOT ALLOCATED
MOV CL,CGTAMX
CALL BDOSMM ;GET AVAILABLE MAXIMUM SIZE
POP CX
MOV AX,SYSMCB+2
CMP 5[SI],AX
JNC ALMEME ;SMALLER THAN MIN SO ERROR END
MOV 7[SI],AX ;SET AVAILABLE MAX AS LENGTH
MOV CL,CALAME
CALL BDOSMM ;ALLOCATE
JMPS ALMEMN ;TO NEXT
;
ALMEMG: ;RELOCATABLE GROUP
ADD BX,5[SI] ;GET TOTAL BY MIN
CMP WORD PTR 7[SI],0
JZ ALMEMM ;NO MAX SO DO BY MIN
ADD DX,7[SI] ;GET TOTAL MAX
JNC ALMEMN ;NOT OVER
MOV DX,0FFF0H ;OVER SO DO BY ABSOLUTE MAX VALUE
JMPS ALMEMN
;
ALMEME: ;ERROR
JMPS SRTGFF
;
ALMEMM: ;NO MAX SPECIFIED SO MIN USED AS MAX
ADD DX,5[SI] ;GET MAX TOTAL
ALMEMN: ;END OF ONE GROUP DESCRIPTOR
ADD SI,9
LOOP ALMEML ;TO NEXT GD
OR DX,DX
JZ ALMEMF ;NO RELOCATABLE LENGTH
MOV SYSMCB+2,DX ;SET MAX LENGTH
MOV CL,CALMEM
CALL BDOSMM ;ALLOCATE RELOCATABLE MEMORY
CMP OTPARB,0
JZ ALMEMF ;OK ALLOCATED
MOV CL,CGTMXM
CALL BDOSMM ;GET MAX SIZE
CMP BX,SYSMCB+2
JA ALMEME ;SMALLER THAN MIN SO ERROR END
MOV CL,CALMEM
CALL BDOSMM ;ALLOCATE BY MAXIMUM AVAILABLE SIZE
MOV DX,SYSMCB+2
SUB DX,BX ;GET SPACE BETWEEN AVAIL TO MIN
CALL STMXGD ;SET AVAILABLE MAX TO GD
ALMEMF:
MOV DI,PNUMCB
MOV AX,FCBSEG
MOV CX,CS
CMP AX,CX
JNZ ALMEMS ;NOT SYSTEM
MOV BYTE PTR 4[DI],1 ;SYSTEM
INC CNUMCB
ALMEMS:
JMPS SRTGFG
;
; SEARCH TARGET GROUP FORM
; INPUT
; AL:TARGET GROUP FORM
; OUTPUT
; SI:GD TOP
; AL:0 OK -1 NOT FOUND
;
SRTGFM:
MOV SI,OFFSET BFGRDC
MOV CX,8
SRTGFL:
CMP [SI],AL
JZ SRTGFG ;GET MATCHED GD
ADD SI,9
LOOP SRTGFL ;TO NEXT
SRTGFF: ;FAIL END
MOV AL,0FFH
RET
;
SRTGFG: ;OK END
MOV AL,0
RET
;
; SETUP MAXIMUM VALUE OF GROUP DESCRIPTOR
; INPUT
; DX:EXTRA SPACE
;
STMXGD:
CMP FMODEL,0FFH
JNZ STMXGN ;NOT 8080 MODEL
MOV BX,BFGRDC+5 ;8080 MODEL
ADD BX,DX
MOV BFGRDC+7,BX ;SO SET IN TOP GD
RET
;
STMXGN: ;NOT 8080 MODEL
MOV AL,2
CALL SRTGFM ;SEARCH DATA GROUP
CMP WORD PTR 7[SI],0
JZ STMXGX ;NO REQUEST OF MAX
MOV DI,SI
MOV AX,3
CALL SRTGFM ;SEARCH EXTRA GROUP
CMP WORD PTR 7[SI],0
JZ STMXGS ;NO REQUEST OF MAX
CALL CMPMRQ ;GET LARGER REQUESTED GROUP
SHR DX,1 ;GET HALF SPACE
MOV BX,DX
ADD BX,5[SI]
CMP BX,7[SI]
JBE STMXGR ;REQUESTED IS LARGER THAN AVAIL HALF
SUB BX,7[SI] ;REQUESTED IS SMALLER
ADD DX,BX ;SO GET LEFT AVAIL SPACE
JMPS STMXGS
;
STMXGR: ;REQUESTED IS LARGER
MOV 7[SI],BX ;SET HALF SPACE
STMXGS:
ADD DX,5[DI]
MOV 7[DI],DX ;SET LEFT SPACE
RET
;
STMXGX: ;DATA GROUP HAS NO REQUEST
MOV AL,3
CALL SRTGFM ;SEARCH EXTRA GROUP
ADD DX,5[SI]
MOV 7[SI],DX ;SET LEFT SPACE
RET
;
; ADD GROUP LENGTH
; INPUT
; SI:GD POINT
; AX:TOTAL
; OUTPUT
; AX:TOTAL
;
ADDGLN:
CMP WORD PTR 7[SI],0
JZ ADDGLS ;NO MAX SO DO BY MIN
ADD AX,7[SI] ;ADD MAX
RET
;
ADDGLS: ;DO BY MIN
ADD AX,5[SI] ;ADD MIN
RET
;
; SETUP LOADING BASE
;
STLDBS:
MOV MODE80,0
MOV AX,SYSMCB ;GET LOADING BASE OF RELOCATABLE
CMP FMODEL,0FFH
JNZ STLDBM ;NOT 8080 MODEL
MOV MODE80,1 ;8080 MODEL
MOV BFGRDC+3,AX ;SET BASE OF TOP GD
MOV DGBASE,AX ;SET SAME BASE TO DATA SEGMENT BASE
JMPS STLDBF
;
STLDBM: ;NOT 8080 MODEL
MOV SI,OFFSET BFGRDC
MOV CX,8
STLDBL: ;ONE GD LOOP
CMP BYTE PTR [SI],0
JZ STLDBA ;NOT ACTIVE
CMP BYTE PTR [SI],2
JNZ STLDBD ;NO DATA GROUP
MOV DGBASE,AX ;SAVE DATA SEGMENT BASE
STLDBD:
CMP WORD PTR 3[SI],0
JNZ STLDBN ;ABSOULTE
MOV 3[SI],AX ;RELOCATABLE SO SET BASE
CMP BYTE PTR [SI],9
JNZ STLDBA
MOV BYTE PTR [SI],1 ;SHARED CODE GROUP SO TO CODE GROUP
STLDBA:
CALL ADDGLN ;ADD GROUP LENGTH
STLDBN:
ADD SI,9
LOOP STLDBL ;TO NEXT GD
STLDBF:
RET
;
; GET ONE PARAGRAPH DATA
; INPUT
; BP:COUNT
; OUTPUT
; SI:DATA POINT
;
GOPGDT:
CMP BP,16*7
JNZ GOPGDS ;NOT END
PUSH BX ;END OF ONE SECTOR SO GET NEXT SECTOR
PUSH ES
CALL READFR ;GET ONE SECTOR
POP ES
POP BX
MOV BP,0 ;CLEAR COUNT
MOV SI,OFFSET BFLDPR ;SET DATA TOP POINT
RET
;
GOPGDS: ;NOT END
ADD BP,16 ;UP COUNT
RET
;
; MAKE LENGTH BY BYTE
; INPUT
; AX:LENGTH BY PARAGRAPH
; OUTPUT
; AH,BX:BYTE LENGTH
;
MKBTLG:
MOV BX,AX
AND AX,0F000H
MOV CL,4
SHR AH,CL ;GET HIGHER 4 BITS
MOV CL,4
SHL BX,CL
SUB BX,1
JNC $+4
DEC AH
RET
;
; 59:LOAD PROGRAM
;
MLOADP:
MOV AX,INDSEG
MOV FCBSEG,AX ;SET FCB SEGMENT
PUSH ES
NOP
MOV UFCBOF,DX ;SET FCB OFFSET
MOV AX,INSTSG
MOV LPSTSG,AX
MOV AX,INSTOF
MOV LPSTOF,AX ;SAVE ENTRY STACK POINTER
MOV DX,CS
MOV CL,CSTDMS
CALL BDOSIS ;SET DATA SEGMENT
MOV DX,OFFSET BFGRDC
MOV CL,CSTDMA
CALL BDOSIS ;SET DMA OFFSET TO GD WORK
CALL READFR ;GET GROUP DESCRIPTOR
CMP OTPARB,0
JZ MLOADS ;OK
MLOADM: ;ERROR END
JMP MLOADR
;
MLOADS:
CALL ALMEMR ;ALLOCATE REQUESTED MEMORY
TEST AL,AL
JNZ MLOADM ;CANNOT ALLOCATE
CALL STLDBS ;SETUP LOADING BASE OF EACH GD
MOV DX,OFFSET BFLDPR
MOV CL,CSTDMA
CALL BDOSIS ;SET DMA OFFSET TO READ WORK
MOV BP,16*7
MOV CX,8
MOV BX,OFFSET BFGRDC
MLOADL: ;ONE GD LOOP
PUSH CX
CMP BYTE PTR [BX],0
JZ MLOADN ;NOT ACTIVE GD
MOV ES,3[BX] ;GET BASE
MOV DI,0
MOV CX,1[BX] ;GET PARAGRAPH LENGTH
JCXZ MLOADN ;NO LENGTH
MLOADG: ;ONE PARAGRAPH LOADING LOOP
PUSH CX
CALL GOPGDT ;GET DATA
MOV CX,8
CLD
REP MOVSW ;MOVE TO TARGET
CMP DI,0
JNZ MLOADB ;NOT 64K BAUNDARY
MOV DX,ES ;UP SEGMENT
ADD DH,010H
MOV ES,DX
MLOADB:
POP CX
LOOP MLOADG ;TO NEXT
MLOADN:
POP CX
ADD BX,9
LOOP MLOADL ;TO NEXT GD
MOV ES,DGBASE ;GET DATA GROUP SEGMENT
MOV OTPARA,ES
MOV DI,0
MOV CX,48
MOV AL,0
CLD
REP STOSB ;CLEAR BASE PAGE
MOV DI,0
MOV AL,MODE80
MOV ES:5[DI],AL ;SET 8080 MODEL MODE
MOV DL,1 ;CODE GROUP FORM
MLOADF: ;ONE FORM TYPE PARAMETER SETUP LOOP
MOV SI,OFFSET BFGRDC
MOV CX,8
MLOADC: ;GD SEARCH LOOP
CMP [SI],DL
JZ MLOADT ;GET TARGET GD
ADD SI,9
LOOP MLOADC ;TO NEXT GD
JMPS MLOADX ;NOT MATCH SO TO NEXT FORM
;
MLOADT: ;GET TARGET GD
MOV AX,3[SI]
MOV ES:3[DI],AX ;SET BASE PARAGRAPH ADDRESS
MOV AX,5[SI]
CMP WORD PTR 7[SI],0
JZ $+5 ;NO MAX SO BY MIN
MOV AX,7[SI] ;GET MAX SIZE
CALL MKBTLG ;TO BYTE LENGTH
MOV ES:2[DI],AH ;SET HIGHER 4 BITS
MOV ES:[DI],BX ;SET LOWER 16 BITS
CMP FMODEL,0FFH
JNZ MLOADX ;NOT 8080 MODEL
ADD DI,6 ;8080 MODEL
MOV ES:2[DI],AH ;SET ALSO IN DATA SEGMENT PARAMETER
MOV ES:[DI],BX
JMPS MLOADE
;
MLOADX: ;TO NEXT FORM
INC DL
ADD DI,6
CMP DL,8
JBE MLOADF ;TO NEXT FORM
MLOADE: ;END OF LOADING
MOV AX,UFCBOF
MOV INPARA,AX
MOV FLINSD,0 ;CLEAR INSIDE MODE
MOV AX,LPSTSG
MOV INSTSG,AX ;RESTORE ENTRY STACK
MOV AX,LPSTOF
JMP MLOADK ;TO RETSTORE & END
;
NOP
;
MLOADR: ;ERROR END
JMP MLOADQ
;
; NOT USED BY PATCH
;
DB 24H,0FFH,0FFH
JMPS MLOADE
;
; 0:SYSTEM RESET
; INPUT PARAMETER:ABORT CODE BYTE
;
MSYRST:
MOV AL,INPARB ;GET ABORT MODE
CMP AL,1
JZ MSYRSR ;MEMORY REMAINING ABORT
MSYRSA:
MOV BYTE PTR .COMBUF+1,0
MSYRSF:
CMP CNUMCB,001H
JA MSYRSC ;SOME MEMORY AREA ACTIVE
CALL MFRALM ;FREE ALL MEMORY
JMPS MSYRSR
;
MSYRSC: ;FREE CURRENT MEMORY
CALL FRCRAR
MOV BX,PNUMCB ;GET USED MCB BUFFER POINT
CALL FREMEM ;FREE LAST MEMORY AREA
DEC CNUMCB ;DOWN USED MCB COUNT
MSYRSR:
MOV FLINSD,0 ;CLEAR BDOS INSIDE MODE
MOV BX,VWBOOT
JMP BIOSCL ;WARM BOOT
;
; 50:DIRECT BIOS CALL
;
MDBIOS:
PUSH DS
MOV DS,INDSEG
MOV BX,DX
MOV AL,[BX] ;GET FUNCTION NUMBER
MOV CX,1[BX] ;GET CX
MOV DX,3[BX] ;GET DX
POP DS
POP BX ;CANCEL END PROCESS DIRECT RETURN TO BDOS MAIN
XOR BX,BX
MOV BL,AL
ADD AL,AL
ADD BL,AL ;*3
ADD BX,VINIT ;GET VECTOR
JMP BX ;TO BIOS ROUTINE
;
; 51:SET DMA SEGMNET
;
MSTDMS:
MOV DMASEG,DX ;SAVE SEGMENT
MOV CX,DX
CALL TOP+VSTDMS ;SET IN BIOS
RET
;
; 52:GET DMA SEGMENT
;
MGTDMS:
MOV BX,DMASEG ;GET SEGMENT
MOV CURSEG,BX ;SAVE SEGMENT
MOV BX,DMAADD ;GET OFFSET
JMP WDPRST
;
; SAVE MCB DATA TO BUFFER
; INPUT
; BX:MCB POINT
;
SVMCBD:
SUB PNUMCB,5 ;DOWN USED MCB BUFFER POINTER
MOV DI,PNUMCB
MOV AX,[BX] ;GET BASE
MOV [DI],AX
MOV AX,2[BX] ;GET LENGTH
MOV 2[DI],AX
MOV BYTE PTR 4[DI],0 ;SET AS CURRENT MODE
ADD CNTREG,1 ;UP COUNT
RET
;
; 53:GET MAXIMUM AVAILABLE MEMORY
;
MGTMXM:
CALL CGBSPR ;CHECK & GET BASE
JNZ MGTMXS ;NO SPACE
CMP SIZREG,0
JZ MALAMR ;NO REGION DATA
CALL GMXRTP ;GET MAXIMUM REGION POINT
MGTMXS:
JNZ MALAMR ;NO SPACE
MOV AX,2[SI]
CMP 2[BX],AX
JC $+5 ;ENOUGH LENGTH
MOV 2[BX],AX ;SHORT SO SET LENGTH
MOV AX,[SI]
MOV [BX],AX ;SET BASE
JMPS MALAMS
;
; 54:GET ABSOLUTE MAXIMUM ADDRESS
;
MGTAMX:
CALL CGBSPR ;CHECK & GET BASE
JNZ MALAMR ;NO SPACE
MGTAML: ;CHECK LOOP
ADD SI,4
INC CL
CMP CL,SIZREG
JNC MALAMR ;ALL OVER
CALL CKABAR ;CHECK REQUESTED AREA WITH TABLE
JNZ MGTAML ;NOT MATCH TO NEXT
MOV AX,2[SI] ;GET MATCHED AREA
ADD AX,[SI] ;GET MAXIMUM ADDRESS
SUB AX,[BX]
CMP 2[BX],AX
JC MGTAME ;ENOUGH LENGTH
MOV 2[BX],AX ;SET LENGTH
MGTAME:
JMPS MALAMS
;
; 55:ALLOCATE MEMORY AREA
;
MALMEM:
CALL CGBSPR ;CHECK & GET BASE
JNZ MALAMR ;NO SPACE
CALL SRSTRG ;SEARCH SUITABLE REGION
JNZ MALAMR ;NO SPACE
CALL GSREGN ;GET & SET REGION
CALL SVMCBD ;SAVE IN USED MCB BUFFER
JMPS MALAMS
;
; 56:ALLOCATE ABSOLUTE MEMORY AREA
;
MALAME:
CALL CGBSPR ;CHECK & GET BASE
JNZ MALAMR ;NO SPACE
MALAML: ;CHECK LOOP
ADD SI,4
INC CL
CMP CL,SIZREG
JNC MALAMR ;ALL OVER
CALL CKABAR ;CHECK REQUESTED AREA WITH TABLE
JNZ MALAML ;NOT MATCH TO NEXT
CALL SRTAAL ;SETUP REGION TABLE
CALL SVMCBD ;SAVE IN USED MCB BUFFER
MALAMS:
MOV AL,SIZREG
MOV 4[BX],AL ;SET REGION NUMBER
XOR AL,AL
JMPS MALAMN ;OK END
;
MALAMR: ;ERROR END
MOV AL,0FFH
MALAMN:
MOV OTPARB,AL
RET
;
; FREE MCB BUFFERED MEMORY AREA
; INPUT
; BX:MCB SAVE BUFFER POINT
;
FREMEM:
MOV AX,2[BX]
MOV SYSMCB+2,AX ;SET LENGTH
MOV AX,[BX]
MOV SYSMCB,AX ;SET BASE
MOV BX,OFFSET SYSMCB
CALL CGBSPA ;CHECK AVAIL
JMPS MFRMES ;FREE SPECIFIED MEMORY ABORT
;
; 57:FREE MEMORY AREA
;
MFRMEM:
CALL CGBSPR
CMP BYTE PTR 4[BX],0FFH
JNZ MFRMES ;SPECIFIED AREA MODE
CALL FRCRAR ;FREE MEMORY AREA ONLY ALLOCATED BY CURRENT PRO
JMPS MALAMS
;
MFRMES: ;FREE SPECIFIED MEMORY AREA
CMP WORD PTR 2[BX],0
JZ MALAMR ;NO LENGTH
CALL CKMRTB ;CHECK WITH BASE TABLE
JNZ MALAMR ;NOT IN RANGE ERROR
CALL CKOVRG ;CHECK OVERLAPPED REGION
JZ MALAMR ;OVERLAPPED SO ERROR
CALL MDUMCB ;MODIFY USED MCB TABLE
CMP AL,0
JNZ MALAMR ;ERROR
CALL CKLMCB ;CHECK MATCHED MCB TABLE BY LOWER
JNZ MFRMEN ;NOT MACTH
MOV DI,SI
MOV CH,CL ;SAVE PARAMETERS
CALL CKUMCB ;CHECK BY UPER
JZ MFRMEE ;EACH SIDE MATCH
MOV AX,2[BX] ;LOWER SIDE MATCH
ADD 2[DI],AX ;UP LENGTH
JMPS MALAMS
;
MFRMEE: ;EACH SIDE MATCH
CALL CHNMCB ;CHAIN TO ONE MCB
JMPS MALAMS
;
MFRMEN: ;NOT MATCH BY LOWER
CALL CKUMCB ;CHECK BY UPER
JNZ MFRMEI ;NOT MATCH
MOV AX,[BX] ;MATCH BY LOWER
MOV [SI],AX ;CHANGE BASE
MOV AX,2[BX]
ADD 2[SI],AX ;UP LENGTH
MFRMEK:
JMPS MALAMS
;
MFRMEI: ;NO MATCH DATA
CALL UGMRTP ;MAKE SPACE IN TABLE
MOV AX,[BX]
MOV [SI],AX ;SET BASE
MOV AX,2[BX]
MOV 2[SI],AX ;SET LENGTH
JMPS MFRMEK
;
; 58:FREE ALL MEMORY
;
MFRALM:
XOR AX,AX
MOV CNTREG,AL ;CLEAR REGION COUNT
MOV CNUMCB,AL ;CLEAR USED MCB BUFFER COUNT
MOV AX,OFFSET TBUMCB+40
MOV PNUMCB,AX ;SET USED MCB BUFFER POINTER TO BOTTOM
CALL TOP+VGTMRT ;GET MEMORY REGION TABLE POINT
MOV SI,BX
MOV CL,[SI] ;GET REGION COUNT
SHL CL,1
SHL CL,1
INC CL ;GET AREA LENGTH
XOR CH,CH
MOV DI,OFFSET SIZREG
CLD
REP MOVSB ;INITIALIZE REGION TABLE
RET
;
; MODIFY USED MCB BUFFER
; INPUT
; BX:REQUESTED MCB POINT
; OUTPUT
; AL:0 OK
;
MDUMCB:
MOV CL,CNTREG
MOV CH,000H
MOV DI,OFFSET TBUMCB+35 ;FIRST USED MCB
MDUMCL: ;CHECK LOOP
MOV AX,[BX]
CMP [DI],AX
JZ MDUMCS ;SAME BASE
JNC MDUMCN ;REQUESTED BASE < TABLE BASE SO TO NEXT
MOV DX,[DI] ;REQUESTED BASE > TABLE BASE
ADD DX,2[DI] ;GET MAXIMUM SEGMENT OF TABLE
ADD AX,2[BX] ;GET MAXIMUM SEGMENT OF REQUESTED
CMP AX,DX
JNZ MDUMCN ;NOT MATCH
MOV AX,2[DI]
SUB AX,2[BX]
MOV 2[DI],AX ;DOWN USED MCB TABLE DATA
JMPS MDUMCE
;
MDUMCN: ;CHECK NEXT
SUB DI,5
LOOP MDUMCL
MDUMCF: ;NOT FOUND END
MOV AL,0FFH
RET
;
MDUMCS: ;SAME BASE
MOV AX,2[BX]
CMP AX,2[DI]
JZ MDUMCV ;SAME LENGTH
JNC MDUMCF ;REQUESTED IS TOO LONG
ADD AX,[DI]
MOV [DI],AX ;UP BASE
MOV AX,2[DI]
SUB AX,2[BX]
MOV 2[DI],AX ;DOWN LENGTH
JMPS MDUMCE ;OK END
;
MDUMCV: ;EVEN REGION
MOV AX,-5[DI] ;COMPRESS USED MCB TABLE
MOV [DI],AX
MOV AX,-3[DI]
MOV 2[DI],AX
MOV AL,-1[DI]
MOV 4[DI],AL
SUB DI,5 ;TO NEXT BLOCK
LOOP MDUMCS
DEC CNTREG ;DOWN COUNT
ADD PNUMCB,5 ;UP POINTER
MDUMCE:
MOV AL,0
RET
;
; FREE MEMORY AREA ONLY ALLOCATED BY CURRENT PROGRAM
;
FRCRAR:
CMP CNTREG,0
JZ FRCRAE ;NO REGION
MOV BX,PNUMCB
CMP BYTE PTR 4[BX],0
JNZ FRCRAE ;NOT CURRENT
CALL FREMEM ;FREE THIS REGION
JMPS FRCRAR ;TO NEXT
;
FRCRAE:
RET
;
; CHECK & GET BASE PARAMETERS
; OUTPUT
; AL:0 OK -1 NO SPACE
; SI:REGION TABLE TOP-4
; CL:BLOCK COUNT-1
;
CGBSPR:
MOV CL,5
CALL STWFCB ;GET MCB
MOV BX,INPARA
CGBSPA:
MOV CL,0FFH
MOV SI,OFFSET TBLREG-4
MOV AL,0FFH
CMP CNTREG,8
JNC CGBSPE ;NO SPACE IN TABLE
CMP WORD PTR 2[BX],0
JZ CGBSPE ;LENGTH ZERO
INC AL
CGBSPE:
OR AL,AL
RET
;
; GET & SET REGION
; INPUT
; SI:TABLE POINT-4
; BX:REQUESTED MCB POINT
; CL:POINT OF TABLE
;
GSREGN:
PUSH CX
MOV AX,2[SI]
SUB AX,2[BX] ;GET LENGTH DIFFERENCE
JNZ GSREGS ;SAME DIFFERENCE
MOV AX,[SI] ;EVEN
MOV [BX],AX ;SAVE BASE
CALL CMPRTB ;COMPRESS
JMPS GSREGE
;
GSREGS:
MOV 2[SI],AX ;SAVE LEFT LENGTH
ADD AX,[SI] ;GET BOTTOM
MOV [BX],AX ;SET AS BASE
GSREGE:
POP CX
RET
;
; COMPRESS REGION TABLE
; INPUT
; CL:TABLE POINT COUNT
; SI:TABLE POINT
;
CMPRTB:
PUSH CX
PUSH SI
PUSH DI
MOV AL,SIZREG
DEC AL
MOV SIZREG,AL ;DOWN COUNT OF TABLE SIZE
SUB AL,CL
JZ CMPRTE ;LAST DATA SO END
MOV CL,AL
XOR CH,CH
ADD CX,CX ;GET LEFT LENGTH COUNT
MOV DI,SI
ADD SI,4
CLD
REP MOVSW ;COMPRESS LEFT DATA
CMPRTE:
POP DI
POP SI
POP CX
RET
;
; GET MAXIMUM REGION TABLE POINT
; INPUT
; SI:REGION TABLE POINT TOP-4
; CL:BLOCK POSITION COUNT -1
; OUTPUT
; SI:MAXIMUM REGION TABLE POINT
; CL:MAXIMUM REGION POINT COUNT
; AL:0 GET -1 NOT FOUND
;
GMXRTP:
PUSH DX
PUSH DI
XOR DX,DX ;CLEAR LENGTH
MOV CH,0FFH
GMXRTL: ;SEARCH LOOP
ADD SI,4
INC CL
CMP CL,SIZREG
JNC GMXRTV ;ALL OVER
MOV AX,2[SI] ;GET LENGTH
CMP AX,DX
JC GMXRTL ;TOO SHORT
MOV DX,AX ;SET CURRENT MAX
MOV CH,CL
MOV DI,SI
JMPS GMXRTL ;TO NEXT
;
GMXRTV:
MOV AL,0FFH
MOV SI,DI
MOV CL,CH
INC CH
JZ GMXRTE ;NO SPACE
INC AL
GMXRTE:
OR AL,AL
POP DI
POP DX
RET
;
; SEARCH SUITABLE REGION
; INPUT
; SI:TABLE-4
; BX:REQUESTED MCB POINT
; OUTPUT
; SI:NEAR OR EVEN REGION POINT
; CL:COUNT OF REGION
; AL:0 OK
;
SRSTRG:
PUSH DX
PUSH DI
MOV DX,-1
MOV CH,0FFH
SRSTRL: ;CHECK LOOP
ADD SI,4
INC CL
CMP CL,SIZREG
JNC SRSTRV ;OVER
MOV AX,2[SI]
SUB AX,2[BX]
JZ SRSTRE ;EVEN LENGTH SO GET
JC SRSTRL ;TOO SHORT
CMP AX,DX
JNC SRSTRL ;TOO LONG
MOV DX,AX ;SET CURRENT
MOV CH,CL
MOV DI,SI
JMPS SRSTRL ;TO NEXT
;
SRSTRV:
MOV AL,0FFH
MOV SI,DI
MOV CL,CH
INC CH
JZ SRSTRE ;NOT FOUND
INC AL
SRSTRE:
OR AL,AL
POP DI
POP DX
RET
;
; GET TOTAL DATA
; INPUT
; BX:MCB POINT
; OUTPUT
; AX:TOTAL DATA
;
GTTODT:
MOV AX,2[BX]
ADD AX,[BX]
RET
;
; GET EACH MAXIMUM ADDRESS
; INPUT
; BP:PARAMETER BUFFER POINT +0 REQUESTED +2 TABLE DATA
; BX:REQUESETED MCB POINT
; SI:TABLE POINT
;
GTEMXA:
PUSH BX
CALL GTTODT
MOV 2[BP],AX ;GET REQUESTED MAX
MOV BX,SI
CALL GTTODT
MOV 0[BP],AX ;GET TABLE MAX
POP BX
RET
;
; CHECK ABSOLUTE AREA
; INPUT
; BX:REQUESTED MCB POINT
; SI:TABLE POINT
; OUTPUT
; AL:0 OK -1 FAIL
;
CKABAR:
PUSH BP
SUB SP,4
MOV BP,SP ;MAKE WORK
PUSH CX
MOV CH,0FFH
CALL GTEMXA ;GET EACH MAX
MOV AX,[BX]
CMP AX,[SI]
JC CKABAE ;REQUESTED BASE < TABLE BASE
MOV AX,0[BP]
CMP AX,2[BP]
JC CKABAE ;REQUESTED MAX < TABLE MAX
MOV CH,0 ;OK GET
CKABAE:
MOV AL,CH
POP CX
ADD SP,4
POP BP
OR AL,AL
RET
;
; UP & GET MAXIMUM REGION TABLE POINT
; OUTPUT
; SI:LAST REGION DATA POINT
;
UGMRTP:
MOV AL,SIZREG
INC SIZREG ;UP COUNT
MOV AH,4
MUL AH
MOV SI,AX ;GET BIAS
LEA SI,TBLREG[SI] ;GET TABLE POINT
RET
;
; SETUP REGION TABLE FOR ABSOLUTE ALLOCATION
; INPUT
; SI:TABLE POINT
; BX:REQUESTED MCB POINT
; CL:TABLE CUNT
;
SRTAAL:
PUSH BP
SUB SP,4
MOV BP,SP ;MAKE WORK
PUSH DX
PUSH CX
CALL GTEMXA ;GET EACH MAX
MOV AX,[BX]
CMP AX,[SI]
JNZ SRTAAD ;NOT SAME BASE
MOV AX,2[BP]
CMP AX,0[BP]
JNZ SRTAAM ;NOT EVEN
POP CX ;EVEN
PUSH CX
CALL CMPRTB ;COMPRESS CURRENT REGION
JMPS SRTAAE
;
SRTAAM: ;LENGTH MISS MATCH
MOV [SI],AX ;SET NEW BASE
MOV AX,2[BX]
SUB 2[SI],AX ;SET NEW LENGTH
JMPS SRTAAE
;
SRTAAD: ;DIFFERENT BASE
MOV AX,0[BP]
SUB AX,2[BP]
JNZ SRTAAB ;NOT EVEN END
MOV AX,[BX] ;EVEN END
SUB AX,[SI]
MOV 2[SI],AX ;DOWN ONLY LENGTH
JMPS SRTAAE
;
SRTAAB: ;MISS MATCH BOTH
MOV AX,[BX]
SUB AX,[SI]
MOV 2[SI],AX ;SET LOWER SPACE LENGTH
CALL UGMRTP ;GET NEW DATA SPACE
MOV AX,2[BP]
MOV [SI],AX ;SET UPER BASE
SUB AX,0[BP]
NEG AX
MOV 2[SI],AX ;SAVE LENGTH
SRTAAE:
POP CX
POP DX
ADD SP,4
POP BP
RET
;
; CHAIN TO ONE MCB
; INPUT
; BX:REQUESTED MCB POINT
; SI:UPER MATCH TABLE POINT
; DI:LOWER MATCH TABLE POINT
;
CHNMCB:
MOV AX,2[BX]
ADD AX,2[SI]
ADD 2[DI],AX ;SET TOTAL LENGTH
CALL CMPRTB ;COMPRESS TABLE
RET
;
; CHECK MEMORY REGION TABLE
; INPUT
; BX:REQUESTED MCB POINT
; OUTPUT
; AL:0 GET
;
CKMRTB:
PUSH CX
PUSH DX
PUSH SI
PUSH BX
CALL TOP+VGTMRT ;GET MEMORY REGION TABLE BASE
MOV CH,[BX] ;GET TABLE SIZE
MOV SI,BX
SUB SI,3 ;TABLE TOP -4
POP BX
MOV CL,0FFH
CKMRTL: ;CHECK LOOP
ADD SI,4
INC CL
CMP CL,CH
JNC CKMRTN ;OVER ALL
CALL CKABAR ;CHECK ABSOLUTE AREA
JNZ CKMRTL ;NOT MATCH
MOV AL,0 ;GET
JMPS CKMRTE
;
CKMRTN: ;NOT MATCH END
MOV AL,0FFH
CKMRTE:
POP SI
POP DX
POP CX
OR AL,AL
RET
;
; CHECK OVERLAPPED REGION
; INPUT
; BX:REQUESTED MCB POINT
; OUTPUT
; AL:0 OVERLAPPED
;
CKOVRG:
PUSH BP
SUB SP,4
MOV BP,SP
PUSH SI
PUSH CX
MOV SI,OFFSET TBLREG-4
MOV CL,0FFH
CKOVRL: ;CHECK LOOP
ADD SI,4
INC CL
CMP CL,SIZREG
JNC CKOVRV ;ALL OVER
CALL GTEMXA ;GET EACH MAX
MOV AX,[BX]
CMP AX,[SI]
JNC CKOVRR ;REQUESTED BASE > TABLE BASE
MOV AX,2[BP]
CMP AX,[SI]
JA CKOVRF ;REQUESTED MAX > TABLE BASE SO OVERLAP
JMPS CKOVRL ;CHECK NEXT
;
CKOVRR: ;REQUESETD BASE > TABLE BASE
CMP AX,0[BP]
JNC CKOVRL ;REQUESTED BASE > TABLE MAX
CKOVRF: ;GET OVERLAPPED REGION
MOV AL,0
JMPS CKOVRE
;
CKOVRV:
MOV AL,0FFH
CKOVRE:
POP CX
POP SI
ADD SP,4
POP BP
OR AL,AL
RET
;
; CHECK MATCHED MCB TABLE BY LOWER
; INPUT
; BX:REQUESTED MCB POINT
; OUTPUT
; SI:MATCHED TABLE POINT
; CL:MATCHED TABLE COUNT
; AL:0 GET
;
CKLMCB:
PUSH BP
SUB SP,4
MOV BP,SP
MOV SI,OFFSET TBLREG-4
MOV CL,0FFH
CKLMCL: ;CHECK LOOP
ADD SI,4
INC CL
CMP CL,SIZREG
JNC CKLMCV ;ALL OVER
CALL GTEMXA ;GET EACH MAX
MOV AX,[BX]
SUB AX,0[BP]
JNZ CKLMCL ;NOT MATCH
JMPS CKLMCE ;MATCH
;
CKLMCV:
MOV AL,0FFH
CKLMCE:
ADD SP,4
POP BP
OR AL,AL
RET
;
; CHECK MATCHED TABLE BY UPER
; INPUT
; BX:REQUESTED MCB POINT
; OUTPUT
; SI:MATCHED TABLE POINT
; CL:MATCHED TABLE COUNT
; AL:0 GET
;
CKUMCB:
PUSH BP
SUB SP,4
MOV BP,SP
MOV SI,OFFSET TBLREG-4
MOV CL,0FFH
CKUMCL: ;CHECK LOOP
ADD SI,4
INC CL
CMP CL,SIZREG
JNC CKUMCV ;OVER
CALL GTEMXA ;GET MAX
MOV AX,2[BP]
SUB AX,[SI]
JNZ CKUMCL ;NOT MATCH
JMPS CKUMCE ;MATCHED
;
CKUMCV:
MOV AL,0FFH
CKUMCE:
ADD SP,4
POP BP
OR AL,AL
RET
;
; CONSOLE I/O ROUTINES
;
; CONSOLE INPUT WITH STORED DATA CHECKING
; OUTPUT
; AL:DATA
;
CONINC:
MOV BX,OFFSET BFCONC
MOV AL,[BX] ;GET BUFFERED DATA
MOV BYTE PTR [BX],0 ;CLEAR DATA
OR AL,AL
JNZ CONCHE ;GET SOME CODE
JMP BCONIN ;GET INPUT BY BIOS CONSOLE INPUT
;
; CONSOLE INPUT BODDY
; OUTPUT
; AL:CODE
;
CONINP:
CALL CONINC ;GET CONSOLE INPUT CODE
CALL CONCHK ;CHECK CONTROL CODE
JC CONCHE ;CONTROL CODE SO NO ECHO
PUSH AX
MOV CL,AL
CALL CONOUT ;ECHO BACK
POP AX
RET
;
; CHECK CONTROL CODE
; INPUT
; AL:CODE
; OUTPUT
; CF:OFF VISIBLE OR VALID CONTROL
;
CONCHK:
CMP AL,CR
JZ CONCHE
CMP AL,LF
JZ CONCHE
CMP AL,HT
JZ CONCHE
CMP AL,BS
JZ CONCHE
CMP AL,' '
CONCHE:
RET
;
; GET CONSOLE STATUS
; OUTPUT
; AL:STATUS 0 NOT READY 1 READY
;
CONSTS:
MOV AL,BFCONC
OR AL,AL
JNZ CONSTD ;EXIST SOME CODE SO READY
CALL BCONST ;CHECK STATUS
AND AL,1
JZ CONCHE ;NO READY
CALL BCONIN ;READY SO GET CODE
CMP AL,'S'-40H
JNZ CONSTG ;NORMAL CODE
CALL BCONIN ;FREEZE MODE WAIT NEXT INPUT
CMP AL,'C'-40H
JZ CONSTA ;ABORT
XOR AL,AL
RET ;NOT READY END
;
CONSTA: ;ABORT
MOV PCARIG,0 ;CLEAR CARRIAGE POSITION
CMP CNUMCB,0
JNZ CONSTM ;SOME MEMORY USED
CALL MRSDSY ;RESET SYSTEM DISK
MOV AL,OTPARB ;GET SUBMIT FILE MODE
MOV .MDSUBE,AL ;SET SUBMIT MODE
JMPS CONSTR
;
CONSTM: ;SOME MEMORY USED
TEST MODABT,0FFH ; NOT SETUP ?????
JZ CONSTE
CMP CNUMCB,1
JNZ CONSTE ;NOT SIMPLE SO RESET ALL
CONSTR:
MOV BYTE PTR .COMBUF+1,0 ;CLEAR COMMAND COUNT
JMP MSYRSR ;RESET SYSTEM WITH MEMORY REMAINDING
;
CONSTE: ;RESET ALL SYSTEM
JMP MSYRSA
;
CONSTG: ;GET CODE
MOV BFCONC,AL ;SAVE CODE
CONSTD:
MOV AL,1 ;READY END
RET
;
; CONSOLE OUT DIRECT
; INPUT
; CL:CODE
;
CONOTS:
MOV AL,ECHKIL
OR AL,AL
JNZ CONOTT ;NO ECHO MODE
PUSH CX
CALL CONSTS ;CHECK CONSOLE IN
POP CX
PUSH CX
CALL BCONOT ;OUT BY BIOS ROUTINE
POP CX
PUSH CX
CMP LSTTGL,0 ;LIST OUT TOGGLE
JZ $+5 ;NO OUT
CALL BLIST ;WITH LIST OUT
POP CX
CONOTT:
MOV AL,CL
MOV BX,OFFSET PCARIG
CMP AL,07FH
JZ CONOTE ;DELETE CODE SO NOT UP
INC BYTE PTR [BX] ;UP CARRIAGE POSITION
CMP AL,' '
JNC CONOTE ;OK VISIBLE CODE
DEC BYTE PTR [BX] ;DOWN AS CONTROL CODE
MOV AL,[BX]
OR AL,AL
JZ CONOTE ;TOP SO OK
MOV AL,CL
CMP AL,BS
JNZ CONOTL ;NOT BACK SPACE
DEC BYTE PTR [BX] ;DOWN AS BACK SPACE
CONOTE:
RET
;
CONOTL:
CMP AL,LF
JNZ CONOTE
MOV BYTE PTR [BX],0 ;LINE FEED SO TOP
RET
;
; CONSOLE OUT WITH CONTROL CODE VISIBLE
; INPUT
; CL:CODE
;
CONOTC:
MOV AL,CL
CALL CONCHK ;CHECK CONTROL CODE
JNC CONOUT ;VISIBLE OR VALID CONTROL CODE
PUSH AX ;UNVISIBLE
MOV CL,'^'
CALL CONOTS ;OUT CONTROL CODE MARK
POP CX
OR CL,040H ;TO VISIBLE CODE
;
; CONSOLE OUT WITH TAB EXPANSION
; INPUT
; CL:CODE
;
CONOUT:
CMP CL,HT
JNZ CONOTS ;OTHER CODE
CONOUL: ;TAB EXPAND LOOP
MOV CL,' '
CALL CONOTS ;OUT SPACE
MOV AL,PCARIG
AND AL,07H
JNZ CONOUL ;NOT TAB POINT
CONOUE:
RET
;
; BACK SPACE WITH ERASE
;
BACKS:
CALL BACK
MOV CL,' '
CALL BCONOT ;ERASE
BACK:
MOV CL,BS
JMP BCONOT
;
; TO NEW LINE WITH END MARK '#' FOR ^U OR SO
;
NCRLF:
MOV CL,'#'
CALL CONOTS
CALL CRLF
NCRLFL: ;TO CURRENT PROMPT POSITION
MOV AL,PCARIG
CMP AL,PPROMP
JNC CONOUE
MOV CL,' '
CALL CONOTS
JMPS NCRLFL
;
; CARRIAGE RETURN & LINE FEED
;
CRLF:
MOV CL,CR
CALL CONOTS
MOV CL,LF
JMP CONOTS
;
; OUT STRING END BY '$'
; INPUT
; CX:STRING POINTER
;
BUFPRN:
MOV SI,CX
LODSB ;GET CODE
CMP AL,'$'
JZ CONOUE ;END
INC CX ;ACTIVE CODE
PUSH CX
MOV CL,AL
PUSH DS
PUSH SS
POP DS
CALL CONOUT ;OUT CODE
POP DS
POP CX
JMPS BUFPRN ;TO NEXT CODE
;
; READ CONSOLE BUFFER
; INPUT
; ES:BUFFER SEGMENT
;
RDCNBF:
MOV AL,PCARIG
MOV PPROMP,AL ;SET PROMPT POSITION
MOV BX,INPARA ;GET BUFFER OFFSET
MOV CL,ES:[BX] ;GET MAX LENGTH
INC BX
PUSH BX ;SAVE LENGTH COUNTER ADDRESS
MOV CH,0 ;CLEAR COUNT
RDCNBL: ;ONE CHARACTER LOOP
PUSH CX
PUSH BX
RDCNBD:
CALL CONINC ;GET CODE
POP BX
POP CX
CMP AL,CR
JNZ $+5 ;NOT END
RDCNBQ: ;END OF INPUT
JMP RDCNBE
;
CMP AL,LF
JZ RDCNBQ ;END CODE
CMP AL,BS
JNZ RDCNBK
OR CH,CH ;BACK SPACE
JZ RDCNBL ;TOP SO DO NOTHING
DEC CH ;DOWN COUNT
MOV AL,PCARIG
MOV ECHKIL,AL ;SAVE CURRENT POINT
JMPS RDCNBI
;
RDCNBK:
CMP AL,07FH
JNZ RDCNBA
OR CH,CH ;DELETE
JZ RDCNBL ;TOP SO DO NOTHING
MOV AL,ES:[BX] ;GET LAST CODE
DEC CH
DEC BX
JMPS RDCNBS ;ECHO LAST CODE
;
RDCNBA:
CMP AL,'E'-40H
JNZ RDCNBP
PUSH CX ;CHANGE LINE
PUSH BX
CALL CRLF
MOV PPROMP,0
RDCNBB:
JMPS RDCNBD
;
RDCNBP:
CMP AL,'P'-40H
JNZ RDCNBC
NOT LSTTGL ;LIST ECHO MODE TOGGLE
JMPS RDCNBL
;
RDCNBC:
CMP AL,'X'-40H
JNZ RDCNBY
POP BX ;ERASE LINE
RDCNBX:
MOV AL,PPROMP ;GET PROMPT POSITION
MOV BX,OFFSET PCARIG
NOP
CMP AL,[BX]
JNC RDCNBF ;REACH TO TOP
NOP
DEC BYTE PTR [BX] ;DOWN POSITION
CALL BACKS ;ERASE & BACK
JMPS RDCNBX ;TO NEXT
;
RDCNBY:
CMP AL,'U'-40H
JNZ RDCNBR
CALL NCRLF ;CANCEL CARRIAGE LINE
POP BX
JMP RDCNBF
;
RDCNBR:
CMP AL,'R'-40H
JNZ RDCNBN
RDCNBI: ;CANCEL LINE & OUT LEFT CODE
PUSH CX
CALL NCRLF
POP CX
POP BX
PUSH BX
PUSH CX
RDCNBG: ;OUT LEFT CODE
OR CH,CH
JZ RDCNBH ;END OF OUT
INC BX
MOV CL,ES:[BX] ;GET CODE
DEC CH
PUSH CX
PUSH BX
CALL CONOTC ;OUT CODE
POP BX
POP CX
JMPS RDCNBG ;TO NEXT
;
RDCNBH:
PUSH BX
MOV AL,ECHKIL ;GET ECHO MODE
OR AL,AL
JZ RDCNBJ ;NORMAL
SUB AL,PCARIG ;KILL MODE
MOV ECHKIL,AL ;GET BACK COUNT
RDCNBO: ;BACK TO LAST POINT
CALL BACKS
DEC ECHKIL
JNZ RDCNBO
RDCNBJ:
JMPS RDCNBB
;
RDCNBN: ;NORMAL CODE
INC BX
MOV ES:[BX],AL ;SET CODE TO BUFFER
INC CH ;UP COUNT
RDCNBS:
PUSH CX
PUSH BX
MOV CL,AL
CALL CONOTC ;ECHO BACK
POP BX
POP CX
MOV AL,ES:[BX]
CMP AL,'C'-40H
MOV AL,CH
JNZ RDCNBM ;NOT ABRT
CMP AL,1
JNZ RDCNBM ;NOT TOP
MOV AX,DS ;ABORT
MOV ES,AX ;RESTORE SEGMENT
JMP CONSTA ;TO ABORT ROUTINE
;
RDCNBM:
CMP AL,CL
JNC RDCNBE ;END OF BUFFER LENGTH
JMP RDCNBL ;TO NEXT
;
RDCNBE: ;END OF INPUT
POP BX
MOV ES:[BX],CH ;SET COUNT
MOV CL,CR
MOV AX,DS
MOV ES,AX
JMP CONOTS ;ECHO LINE END
;
; 1:CONSOLE INPUT
;
MCONIN:
CALL CONINP
JMPS BTPRST
;
; 3:READER INPUT
;
MREDER:
CALL TOP+VREADR
JMPS BTPRST
;
; 6:DIRECT CONSOLE I/O
; INPUT
; CL:-1 INPUT/STATUS -2 STATUS OTHER OUTPUT
;
MDCNIO:
MOV AL,CL
INC AL
JZ MDCNIS ;INPUT/STATUS
INC AL
JNZ BCONOT ;OUTPUT
CALL BCONST ;STATUS
JMPS BTPRST
;
MDCNIS: ;INPUT/STATUS
CALL BCONST
OR AL,AL
JNZ MDCNIG ;GET SOME CODE
JMP ENDPRN ;NOT READY
;
MDCNIG: ;GET SOME CODE
CALL BCONIN ;GET CODE
JMPS BTPRST
;
; 7:GET I/O BYTE
;
MGTIOB:
CALL TOP+VGTIOB
JMPS BTPRST
;
; 8:SET I/O BYTE
;
MSTIOB:
MOV CX,DX
CALL TOP+VSTIOB
RET
;
; 9:CONSOLE OUT STRING END BY '$'
;
MBUFPR:
MOV CX,DX
PUSH DS
MOV DS,INDSEG
CALL BUFPRN
POP DS
RET
;
; 10:READ CONSOLE BUFFER
;
MRDCBF:
MOV ES,INDSEG
JMP RDCNBF
;
; 11:GET CONSOLE STATUS
;
MCONST:
CALL CONSTS
;
; SET BYTE RESULT & END
;
BTPRST:
MOV OTPARB,AL
NOPROC:
RET
;
; NO DATA EXIST END IN DISK OPERATION
;
NODTEX:
MOV AL,1
JMPS BTPRST
;
; BIOS ROUTINE CALL
;
; 5:LIST OUT
;
BLIST:
MOV BX,VLIST
JMPS BIOSCL
;
; CONSOLE INPUT
;
BCONIN:
MOV BX,VCONIN
JMPS BIOSCL
;
; CONSOLE STATUS
;
BCONST:
MOV BX,VCONST
JMPS BIOSCL
;
; CONSOLE OUTPUT
;
BCONOT:
MOV BX,VCONOT
;
; BIOS CALL
; INPUT
; BX:ROUTINE ADDRESS
;
BIOSCL:
CALLF DWORD PTR JPBIOS
RET
;
;
DBIOS:
CALL BX ;TO EACH ROUTINE
RETF
;
; DISK I/O ROUTINES
;
; SELECT ERROR
;
DSEROR:
MOV BX,OFFSET VSELCT
ERROR: ;ERROR COMMON ROUTINE
JMP WORD PTR [BX]
;
; COPY DATA
; INPUT
; DX:SOURCE POINTER
; BX:DESTINATION POINTER
; CL:LENGTH
;
COPY:
PUSH CX
MOV CH,0
MOV SI,DX
MOV DI,BX
CLD
REP MOVSB ;COPY DATA
POP CX
RET
;
; SELECCT & GET DISK PARAMETER
; OUTPUT
; ZF:ON NO UNIT
;
GDPTBL:
MOV CL,CURDSK
CALL TOP+VSLDSK ;SELECT DISK BY BIOS ROUTINE
CMP BX,0
JZ GDPTBE ;NOT ACTIVE DISK END
MOV DX,[BX] ;GET TRANSLATION TABLE POINT
ADD BX,2
MOV PNDRCK,BX ;DIRECTORY CHECK LEVEL WORK POINT
ADD BX,2
MOV PNTRAK,BX ;TRACK NUMBER WORK POINT
ADD BX,2
MOV PNSCTR,BX ;TOTAL SECTOR WORK POINT
ADD BX,2
XCHG BX,DX
MOV PNXTBL,BX ;SAVE TRANSLATION TABLE POINT
MOV BX,DIRBUF
MOV LSDRBF,BX ;SAVE LAST DIRECTORY BUFFER POINT NOT USED ??
MOV BX,OFFSET DIRBUF
MOV CL,8
CALL COPY ;GET DISK PARAMETER HEADER DATA
MOV DX,PNTDPB ;DISK PARAMETER BLOCK POINT
MOV BX,OFFSET SPT
MOV CL,15
CALL COPY ;GET DISK PARAMETER BLOCK DATA
MOV AL,BYTE PTR DSM+1
MOV BX,OFFSET DSMMOD
MOV BYTE PTR [BX],0FFH
OR AL,AL
JZ $+5 ;DSM <= 255 ONE BYTE MODE
MOV BYTE PTR [BX],0 ;DSM > 256 TWO BYTE MODE
MOV AL,0FFH
OR AL,AL
GDPTBE:
RET
;
; TO HOME FOR DIECTORY READ
;
TOHOME:
CALL TOP+VHOME
XOR AX,AX
MOV BX,PNTRAK
MOV [BX],AX ;CLEAR CURRENT TRACK WORK
RET
;
; ONE SECTOR READ
;
DREAD:
MOV DX,TGSECT ; ?????
CALL TOP+VDREAD
JMPS DWRITN
;
; ONE SECTOR WRITE
;
DWRITE:
MOV CL,MDWRIT ;GET WRITE MODE
DWRITS:
CALL TOP+VDWRIT
DWRITN:
OR AL,AL
JZ GDPTBE ;OK END
MOV BX,OFFSET VBADSC ;DISK READ / WRITE ERROR
JMP ERROR
;
; SET DIRECTORY TRACK & SECTOR
;
STDIRT:
MOV BX,DIRCNT
MOV CL,2
SHR BX,CL ;GET SECTOR COUNT
MOV TGSECT,BX ;SET TARGET SECTOR
MOV DIRSCT,BX ;SAVE SECTOR
;
; SET PHYSICAL TRACK & SECTOR
;
TRSSET:
MOV AX,TGSECT
MOV DX,0
DIV SPT ;GET TRACK & SECTOR
PUSH DX ;SAVE SECTOR
MOV CX,AX
MOV SI,PNTRAK
MOV [SI],CX ;SET TARGET TRACK
ADD CX,TRKOFF ;GET PHYSICAL TRACK
CALL TOP+VSTTRK ;SET TRACK
POP CX
MOV DX,PNXTBL ;TRANSLATION TABLE POINT
CALL TOP+VSCTRN ;TO PHYSICAL SECTOR
MOV CX,BX
JMP TOP+VSTSEC ;SET PHYSICAL SECTOR
;
; GET BIAS IN DIRECTORY
; OUTPUT
; AL:BIAS
;
GBSDIR:
MOV BX,OFFSET BSH
MOV CL,[BX] ;GET BLOCK SHIFT FACTOR
MOV AL,CURCNT ;GET CURRENT COUNT
SHR AL,CL
MOV CH,AL ;GET BIAS BY CURRENT COUNT
MOV CL,7
SUB CL,[BX] ;GET SHIFT FACTOR OF EXTENT
MOV AL,EXTENT
SHL AL,CL ;GET BIAS BY EXTENT
ADD AL,CH ;GET TOTAL BIAS
RET
;
; GET BLOCK NUMBER
; INPUT
; CX:BIAS IN DIRECTORY
; OUTPUT
; BX:BLOCK NUMBER
;
GTBLNM:
MOV BX,INPARA
ADD BX,16 ;GET DIRECTORY MAP TOP
ADD BX,CX ;GET MAP POINT ( IF ONE BYTE )
CMP DSMMOD,0 ;CHECK MAP MODE
JZ GTBLNS ;TWO BYTE MODE
MOV BL,[BX] ;ONE BYTE MODE
MOV BH,0 ;GET BLOCK NUMBER
RET
;
GTBLNS: ;TWO BYTE MODE
ADD BX,CX ;GET MAP POINT ( TWO BYTE MODE )
MOV BX,[BX] ;GET BLOCK NUMBER
RET
;
; GET TARGET BLOCK
;
GTBLCK:
CALL GBSDIR ;GET BIAS IN DIRECTORY
MOV CL,AL
MOV CH,0
CALL GTBLNM ;GET BLOCK NUMBER
MOV TGSECT,BX ;SET TO TARGET WORK
RET
;
; CHECK BLOCK EMPTY
; OUTPUT
; ZF:ON EMPTY
;
CHKBLK:
MOV BX,TGSECT
OR BX,BX
RET
;
; BLOCK NUMBER TO LOGICAL SECTOR
;
BLTSCT:
MOV CL,BSH
MOV BX,TGSECT
SHL BX,CL ;GET BLOCK TOP SECTOR
MOV BTSECT,BX ;SAVE BLOCK TOP
MOV AL,CURCNT ;GET CURRENT COUNT
AND AL,BLM ;GET BIAS IN BLOCK
OR BL,AL ;GET TOTAL SECTOR
MOV TGSECT,BX ;SAVE TOTAL LOGICAL SECTOR
RET
;
; GET EXTENT POINT & DATA
; OUTPUT
; AL:EXTENT
; BX:DATA POINT
;
EXTPNT:
MOV BX,INPARA
ADD BX,12
MOV AL,[BX] ;GET EXTENT
RET
;
; GET RECORD COUNT POINT
; OUTPUT
; BX:CURRENT RECORD COUNT POINT
; DX:RECORD COUNT POINT
;
GTRCPT:
MOV DX,15
ADD DX,INPARA ;RECRD COUNT POINT
MOV BX,17
ADD BX,DX ;CURRENT RECORD COUNT POINT
RET
;
; GET RECORD COUNT DATA
;
GTRCNT:
CALL GTRCPT ;GET RECORD COUNT POINT
MOV AL,[BX] ;GET CURRENT RECORD
MOV CURCNT,AL ;SAVE
XCHG BX,DX
MOV AL,[BX] ;GET RECORD COUNT
MOV RECUNT,AL ;SAVE
CALL EXTPNT ;GET EXTENT POINT
MOV AL,EXM ;GET EXTENT MASK
AND AL,[BX] ;GET MASKED EXTENT
MOV EXTENT,AL
RET
;
; UP & SET RECORD COUNT TO FCB
;
USRCNT:
CALL GTRCPT ;GET RECORD COUNT POINT
MOV AL,RUPCNT ;GET COUNT UP COUNT
CMP AL,2
JNZ $+4 ;0 RANDOM OR 1 SEQUENTIAL
XOR AL,AL ;RANDOM WRITE WITH ZERO FILL SO NOT UP
ADD AL,CURCNT ;UP CURRENT RECORD COUNT
MOV [BX],AL ;SAVE CURRENT RECORD
XCHG BX,DX
MOV AL,RECUNT
MOV [BX],AL ;SET RECORD COUNT
RET
;
; GET HASH TOTAL FOR DIRECTORY CHECK SUM
; OUTPUT
; AL:HASH TOTAL
;
HASH:
MOV CX,128 ;SECTOR LENGTH
MOV BX,DIRBUF
XOR AL,AL
HASHL: ;TOTAL LOOP
ADD AL,[BX]
INC BX
LOOP HASHL
RET
;
; SET CURRENT DISK BIT
; INPUT
; CX:BASE VECTOR
; OUTPUT
; BX:NEW VECTOR
;
STDKVC:
PUSH CX
MOV CL,CURDSK
MOV BX,1
SHL BX,CL ;GET CURRENT DISK BIT
POP CX
OR BX,CX
RET
;
; CHECK R/O DISK VECTOR
; OUTPUT
; ZF:ON R/W DISK OFF R/O DISK
;
CHKROV:
MOV AX,RODSKV ;GET R/O DISK VECTOR
MOV CL,CURDSK
SHR AX,CL
AND AL,1 ;GET MODE
RET
;
; 28:WRITE PROTECT DISK
;
MWPDSK:
MOV CX,RODSKV ;GET R/O DISK VECTOR
CALL STDKVC ;SET CURRENT DISK BIT
MOV RODSKV,BX ;SAVE NEW R/O DISK VECTOR
MOV DX,DRM
INC DX ;GET DIRECTORY MAXIMUM
MOV BX,PNDRCK
MOV [BX],DX ;DIRECTORY CHECK LEVEL TO FULL
RET
;
; CHECK WRITE PROTECT FILE
;
CHKROF:
CALL GTDRPT ;GET FCB POINT IN DIRECTORY
CHKROL:
MOV DX,9
ADD BX,DX
MOV AL,[BX] ;GET R/O BYTE
RCL AL,1
JNC GTDRPE ;R/W FILE
MOV BX,OFFSET VROFIL ;R/O FILE
JMPS CHKROE ;ERROR
;
; CHECK WRITE PROTECT DISK
;
CHKROD:
CALL CHKROV ;CHECK R/O DISK
JZ GTDRPE ;R/W DISK
MOV BX,OFFSET VRODSK ;R/O DISK ERROR
CHKROE: ;ERROR END
JMP ERROR
;
; GET DIRECTORY POINT
;
GTDRPT:
MOV BX,DIRBUF
MOV AL,BISDIR ;GET BIAS IN DIRECTORY
MOV AH,0
ADD BX,AX ;GET POINT
GTDRPE:
RET
;
; GET FILE MODE
; OUTPUT
; BX:FILE MODE DATA POINT
; AL:B7:WRITE OPERATION MODE READ ONLY
; B6:RANDOM READ/WRITE ERROR
; B0-4:EXTENTION OF EXTENT
;
FMDPNT:
MOV BX,INPARA
ADD BX,14
MOV AL,[BX]
RET
;
; CLEAR FILE MODE
;
FMDCLR:
CALL FMDPNT
MOV BYTE PTR [BX],0
RET
;
; INITIALIZE FILE MODIFY MODE
;
FMDRON:
CALL FMDPNT
OR AL,80H
MOV [BX],AL
RET
;
; CHECK DIRECTORY LEVEL
; OUTPUT
; DX:CURRENT DIREORY COUNT
; BX:DIRETCORY DATA POINT
; CF:ON UNDER
;
CHKDLV:
MOV DX,DIRCNT
MOV BX,PNDRCK
CMP DX,[BX]
CHKDLE:
RET
;
; CHECK & SET DIRECTORY LEVEL
;
STDLVL:
CALL CHKDLV
JC CHKDLE ;UNDER
INC DX ;UP DIRECTORY COUNT
MOV [BX],DX ;SAVE NEW MAXIMUM LEVEL
RET
;
; INVERTED SUBTRACT
; BX=DX-BX
;
INVSUB:
PUSH DX
SUB DX,BX
MOV BX,DX
POP DX
RET
;
; SET OR CHECK DIRECTORY HASH (CHECK SUM)
; INPUT
; CL:0 CHECK -1 SET
;
HASHST:
MOV CL,-1 ;SET CHECK SUM
HASHSC:
MOV DX,DIRSCT ;GET SECTOR OF CURRENT DIRECTORY
MOV BX,CHKSIZ
CALL INVSUB
JNC CHKDLE ;OVER OF CHECKED DIRECTORY SIZE
PUSH CX
CALL HASH ;GET HASH TOTAL OF DIRECTORY DATA
MOV BX,DIRSCT
ADD BX,PNCHSM
POP CX
INC CL
JZ HASHSS ;SET MODE
CMP AL,[BX] ;CHECK MODE
JZ HASHSE ;OK END
CALL CHKDLV ;MISS MATCH
JNC HASHSE ;CHECKED DIRECTORY LEVEL IS LOWER
CALL MWPDSK ;ERROR MAYBE CHANGED MEDIA SO TO R/O DISK
RET
;
HASHSS: ;SET MODE
MOV [BX],AL ;SET SUM DATA
HASHSE: ;OK END
RET
;
; WRITE DIRECTORY
;
DRWRIT:
CALL HASHST ;SET NEW CHECK SUM DATA
CALL STDDMA ;DMA ADDRESS TO DIRECTORY BUFFER
MOV CL,1
CALL DWRITS ;WRITE AS DIRECTORY
JMPS STBDMA ;RESTORE DMA ADDRESS
;
; READ DIRECTORY
;
DRREAD:
CALL STDDMA ;DMA ADDRESS TO DIRECTORY BUFFER
CALL DREAD ;READ DIRECTORY SECTOR
;
; SET BASE DMA ADDRESS
;
STBDMA:
MOV CX,DMASEG
CALL TOP+VSTDMS ;SET SEGMENT
MOV BX,OFFSET DMAADD
JMPS STDDMS ;SET OFFSET
;
; SET DMA ADDRESS TO DIRECTORY BUFFER
;
STDDMA:
MOV CX,DS
CALL TOP+VSTDMS ;SET SEGMENT
MOV BX,OFFSET DIRBUF
STDDMS: ;SET OFFSET
MOV CX,[BX]
JMP TOP+VSTDMA
;
; COPY DIRECTORY DATA TO USER DMA AREA
;
DRCOPY:
MOV DX,DIRBUF
MOV BX,DMAADD
MOV CL,128 ;SECTOR LENGTH
PUSH ES
MOV ES,DMASEG
CALL COPY ;COPY DATA
POP ES
RET
;
; CHECK DIRECTORY END
; OUTPUT
; ZF:ON END
;
CKDREN:
MOV BX,OFFSET DIRCNT
MOV AL,[BX]
INC BX
CMP AL,[BX]
JNZ CKDREE ;NOT END
INC AL ;0FFFFH IS END CODE
CKDREE:
RET
;
; INITIALIZE DIRECTORY COUNT
;
INDRCN:
MOV BX,-1
MOV DIRCNT,BX
RET
;
; GET NEXT DIRECTORY SECTOR
; INPUT
; CL:0 CHECK -1 SET DIRECTORY CHECK SUM
;
GTNDSC:
MOV DX,DRM ;GET MAX OF DIRECTORY
MOV BX,DIRCNT
INC BX
MOV DIRCNT,BX ;UP DIRECTORY COUNT
CALL INVSUB ;CHECK OVER
JNC GTNDSS ;IN RANGE
JMPS INDRCN ;OVER OF DIRECTORY
;
GTNDSS:
MOV AL,BYTE PTR DIRCNT
AND AL,3 ;GET BIAS IN SECTOR
PUSH CX
MOV CL,5
SHL AL,CL ;*32 GET BIAS BY BYTE
POP CX
MOV BISDIR,AL ;SAVE BIAS
OR AL,AL
JNZ GTDMBE ;NOT TOP SO ALREADY DATA READ
PUSH CX ;TOP SO READ NEW SECTOR
CALL STDIRT ;SET DIRECTORY TRACK & SECTOR
CALL DRREAD ;READ DIRECTORY DATA
POP CX
JMP HASHSC ;CHECK OR SET DIRECTORY CHECK SUM
;
; GET DIRECTORY ALLOCATION MAP BIT
; INPUT
; CX:TARGET BLOCK NUMBER
; OUTPUT
; AL:BIT 0 IS TARGET BIT
; DH:ROTATE COUN IN BYTE
; BX:MAP POINT
;
GTDMBT:
MOV DX,CX
AND CL,7 ;GET BIAS IN BYTE
INC CL
MOV CH,CL
MOV CL,3
SHR DX,CL ;GET BIAS OF BYTE
MOV BX,PNALMP
ADD BX,DX ;GET MAP POINT
MOV AL,[BX] ;GET MAP DATA
MOV CL,CH
ROL AL,CL ;ROTATE TO TARGET BIT
MOV DX,CX
GTDMBE:
RET
;
; CHANGE DISK ALLOCATION MAP BIT
; INPUT
; CX:BLOCK NUMBER
; DL:0 DELETE 1 SET
;
CGDMBT:
PUSH DX
CALL GTDMBT ;GET MAP BIT
AND AL,0FEH ;OFF BIT
POP CX
OR AL,CL ;SET OR NOT SET
;
; SET DISK ALLOCATION MAP BIT
; INPUT
; AL:BYTE DATA
; DH:ROTATE COUNT
; BX:MAP POINT
;
STDMBT:
PUSH CX
MOV CL,DH
ROR AL,CL
MOV [BX],AL ;SET TO ALLOCATION MAP
POP CX
RET
;
; CHANGE DISK ALLOCATION MAP BY ONE DIRECTORY DATA
; INPUT
; CL:0 DELETE 1 USE
;
CHGDMP:
CALL GTDRPT ;GET DIRECTORY BLOCK TOP
ADD BX,16
PUSH CX
MOV CL,17 ;BLOCK NUMBER DATA +1
CHGDML: ;ONE BLOCK SET/CLEAR LOOP
POP DX
DEC CL
JNZ CHGDMS ;NOT END
RET ;END OF ONE DIRECTORY
;
CHGDMS:
PUSH DX
CMP DSMMOD,0 ;CHECK BLOCK NUMBER MODE
JZ CHGDMT ;TWO BYTE MODE
PUSH CX ;ONE BYTE MODE
PUSH BX
MOV CL,[BX] ;GET BLOCK NUMBER
MOV CH,0
JMPS CHGDMG
;
CHGDMT: ;TWO BYTE MODE
DEC CL
PUSH CX
MOV CX,[BX] ;GET BLOCK NUMBER
INC BX
PUSH BX
CHGDMG:
OR CX,CX
JZ CHGDMN ;NOT ALLOCATED
MOV BX,DSM
CMP BX,CX
JC CHGDMN ;OVER OF SIZE
CALL CGDMBT ;SET/CLEAR TARGET BIT IN MAP
CHGDMN: ;TO NEXT BLOCK NUMBER
POP BX
INC BX
POP CX
JMPS CHGDML
;
; INITIALIZE DISK ALLOCATION MAP & CHECK SUM TABLE
;
INIDMP:
MOV BX,DSM
MOV CL,3
SHR BX,CL
INC BX ;GET ALL MAP SIZE
MOV CX,BX
MOV BX,PNALMP ;MAP TOP
INIDMC: ;CLEAR OF ALLOCATION MAP
MOV BYTE PTR [BX],0
INC BX
LOOP INIDMC
MOV DX,ALMASK ;GET DIRECTORY RESERVED BIT
MOV BX,PNALMP
MOV [BX],DX ;SET INITIAL DATA OF ALLOCATION MAP
CALL TOHOME ;RESTORE
MOV BX,PNDRCK
MOV WORD PTR [BX],3 ;INITIALIZE DIRETORY CHECK LEVEL
CALL INDRCN ;INITIALIZE DATA COUNT
INIDML:
MOV CL,-1
CALL GTNDSC ;GET NEXT DIRECTORY
CALL CKDREN ;CHECK END
JZ CPEXTE ;END OF DIRECTORY
CALL GTDRPT ;GET DIRECTORY POINT
CMP BYTE PTR [BX],DELCOD
JZ INIDML ;DELETED FILE
MOV AL,USRCOD
CMP AL,[BX]
JNZ INIDMS ;NOT CURRENT USER DIRECTORY
INC BX
MOV AL,[BX]
SUB AL,'$'
JNZ INIDMS ;NOT SUBMIT TEMPORARY
DEC AL
MOV OTPARB,AL ;SUBMIT TEMPORARY EXISTS
INIDMS:
MOV CL,1
CALL CHGDMP ;SET DISK ALLOCATION MAP BIT
CALL STDLVL ;UP DIRECTROY LEVEL AS AVAILABLE
JMPS INIDML
;
; SET DIRECTORY CODE -1 NOT FOUND
;
SDRCOD:
MOV AL,DIRCOD
JMP BTPRST
;
; COMPARE DIRECTORY EXTENSION AS DIRECTORY NUMBER
; INPUT
; AL:CODE 1
; CL:CODE 2
; OUTPUT
; AL:DIRECTORY DIFFERENCE
; ZF:ON EVEN
;
CPEXTM:
PUSH CX
MOV CH,EXM
NOT CH ;GET MASK AS DIREORY NUMBER
AND CL,CH
AND AL,CH
SUB AL,CL
AND AL,01FH ;EXTENT AVAILABLE ONLY 5 BITS
POP CX
CPEXTE:
RET
;
; SET DIRECTORY SEARCH PARAMETER
; INPUT
; CL:COMPARE LENGTH
;
STDRSP:
MOV BX,INPARA
MOV FCBOFF,BX ;SET FCB OFFSET
MOV DIRCOD,-1 ;INITIALIZE DIRECTORY CODE AS NOT FOUND
MOV DIRCLN,CL ;SET COMPARE LENGTH
RET
;
; SEARCH DIRECTORY FROM TOP
; INPUT
; CL:COMPARE LENGTH 0,1,12,15, ETC
;
SRDRFS:
CALL STDRSP ;SET DIRECTORY SEARCH PARAMETER
CALL INDRCN ;INITIALIZE DIRECTORY COUNT
CALL TOHOME ;RESTORE
;
; SEARCH DIRECTORY OF NEXT
; OUTPUT
; CH:DIRECTORY CODE +1
;
SRDRNX:
MOV SYSFLG,0 ;CLEAR USER 0 MATCH MODE
MOV CL,0 ;HASH MODE TO CHECK
CALL GTNDSC ;GET DIRECTORY DATA
CALL CKDREN ;CHECK END
JNZ SRDRNS ;NOT END
SRDRNO: ;END OF DIRECTORY
JMP SRDRNF ;NOT FOUND END
;
SRDRNS:
MOV DX,FCBOFF
MOV SI,DX
LODSB ;GET TOP CODE
CMP AL,DELCOD
JZ SRDRND ;DELETED FILE SEARCH MODE
PUSH DX
CALL CHKDLV ;CHECK DIRECTORY LEVEL
POP DX
JNC SRDRNO ;OVER ACTIVE DIRECTORY
SRDRND:
CALL GTDRPT ;GET DIRECTORY POINT
MOV CL,DIRCLN ;COMPARE LENGTH
MOV CH,0 ;CLEAR COUNT
SRDRNL: ;ONE BYTE COMPARE LOOP
OR CL,CL
JZ SRDRNG ;END OF COMPARE MATCHED
MOV SI,DX
LODSB ;GET CODE
CMP AL,'?'
JZ SRDRNN ;WILD CARD SO DO NOT CARE
CMP CH,13
JZ SRDRNN ;SYSTEM BYTE SO IGNORED
CMP CH,12
JZ SRDRNE ;FILE EXTENT
SUB AL,[BX]
AND AL,07FH
JNZ SRDRNM ;MISS MATCH
JMPS SRDRNN ;MATCH
;
SRDRNE: ;FILE EXTENT
PUSH CX
MOV CL,[BX]
CALL CPEXTM ;COMPARE EXTENT AS DIRECTORY NUMBER
POP CX
LAHF
TEST SYSFLG,0FFH
JNZ SRDRNZ ;USER CODE MISS MATCH USER 0
MOV SYSSRC,0 ;CLEAR USER 0 SEARCH MODE AS SAME NAME FILE
SAHF
JNZ SRDRNX ;EXTENT MISS MATCH
SRDRNN: ;MATCH TO NEXT BYTE
INC DX
INC BX
INC CH
DEC CL
JMPS SRDRNL
;
SRDRNG: ;OK GET MATCHED DIRECTORY
MOV DIRCOD,0 ;USER DIRECTORY CODE MODE
MOV AL,BYTE PTR DIRCNT
AND AL,3
MOV OTPARB,AL ;SET DIRECTORY CODE
MOV CH,AL
INC CH
SRDRNR:
RET
;
SRDRNM: ;MISS MATCH OF BYTE
OR CH,CH
JNZ SRDRNT ;NOT TOP
TEST BYTE PTR [BX],0FFH
JNZ SRDRNT ;NOT USER ZERO
TEST SYSSRC,0FFH
JZ SRDRNT ;NOT USER 0 SEARCH MODE
MOV SYSFLG,0FFH ;SET USER 0 DIRECTORY MODE
JMPS SRDRNN
;
SRDRNF: ;NOT FOUND END
CALL INDRCN ;INITIALIZE COUNT
MOV AL,0FFH ;FAIL END CODE
MOV CH,AL
INC CH
JMP BTPRST
;
SRDRNZ: ;USER 0 MISS MATCH FILE
SAHF
JNZ SRDRNT ;EXTENT MISS MATCH
INC BX
CMP BYTE PTR [BX],0
JNZ SRDRNT ;MISS MATCH
MOV SI,DIRCNT
MOV SYSCNT,SI ;SAVE MATCHED DIRECTORY COUNT
SRDRNT:
JMP SRDRNX ;TO NEXT
;
; DELETE DIRECTORY & ALLOCATION MAP
;
DELDMP:
CALL CHKROD ;CHECK R/O DISK
MOV CL,12 ;COMPARE ONLY NAME PART
CALL SRDRFS ;SEARCH FIRST
DELDML: ;ONE DIRECTORY ERASE LOOP
CALL CKDREN ;CHECK END
JZ SRDRNR ;ALL OVER
CALL CHKROF ;CHECK R/O FILE
CALL GTDRPT ;GET DIRECTORY POINT
MOV BYTE PTR [BX],DELCOD ;SET DELETE CODE
MOV CL,0 ;DELETE MODE
CALL CHGDMP ;DELETE ALL MAP
CALL DRWRIT ;WRITE DIRECTORY
CALL SRDRNX ;SEARCH NEXT
JMPS DELDML ;TO NEXT DIRECTORY
;
; GET AVAILABLE BLOCK BY SEARCHING NEAREST BLOCK
; INPUT
; CX:LAST BLOCK NUMBER 0 FIRST BLOCK
; OUTPUT
; BX:AVAILABLE BLOCK NUMBER 0 NO SPACE
;
GAVLBK:
MOV DX,CX
GAVLBL: ;SEARCH LOOP CX LOWER SEARCH DX UP SEARCH
OR CX,CX
JZ GAVLBS ;NO LOWER SPACE
DEC CX
PUSH DX
PUSH CX
CALL GTDMBT ;GET ALLOCATION MAP BIT
RCR AL,1
JNC GAVLBA ;GET AVAILABLE BLOCK
POP CX ;NOT AVAILABLE
POP DX
GAVLBS: ;SEARCH UPER
CMP DX,DSM
JNC GAVLBE ;NO UPER SPACE
INC DX
PUSH CX
PUSH DX
MOV CX,DX
CALL GTDMBT ;GET ALLOCATION MAP BIT
RCR AL,1
JNC GAVLBA ;GET AVAILABLE BLOCK
POP DX ;NO AVAILABLE
POP CX
JMPS GAVLBL ;CHECK NEXT
;
GAVLBA: ;GET AVAILABLE BLOCK
RCL AL,1
INC AL ;ON BIT FOR USE
CALL STDMBT ;SET TO ALLOCATION MAP
POP BX
POP DX
RET
;
GAVLBE: ;NO UPER SPACE
OR CX,CX
JNZ GAVLBL ;SOME LOWER SPACE LEFT
MOV BX,0 ;NO DISK SPACE
RET
;
; COPY ALL FCB DATA TO DIRECTORY & WRITE
; INPUT
; CL:BIAS OF FCB SOURCE TOP 0 NORMAL 16 REBAME
; DL:COPY LENGTH
;
COPYDA:
MOV CL,0 ;FOR ALL COPY MODE
MOV DL,32
COPYDR:
PUSH DX ;SAVE LENGTH
MOV CH,0
MOV DX,INPARA
ADD DX,CX ;GET SOURCE POINT
CALL GTDRPT ;GET DIRECTORY TOP
POP CX
CALL COPY ;COPY
COPYDE:
CALL STDIRT ;SET DIRECTORY TRACK & SECTOR
JMP DRWRIT ;WRITE DIRECTORY
;
; RENAME
;
RENAME:
CALL CHKROD ;CHECK R/O DISK
MOV CL,12 ;ONLY NAME
CALL SRDRFS ;SEARCH FIRST
MOV BX,INPARA
MOV AL,[BX]
ADD BX,16
MOV [BX],AL ;SET SAME USER CODE TO NEW NAME
RENAML: ;ONE DIRECTORY RENAME LOOP
CALL CKDREN ;CHECK END
JNZ RENAMS ;NOT END
RENAMN: ;END
RET
;
RENAMS:
CALL CHKROF ;CHECK R/O FILE
MOV CL,16 ;NEW NAME
MOV DL,12 ;COPY LENGTH
CALL COPYDR ;SET NEW NAME & WRITE
CALL SRDRNX ;SEARCH NEXT
JMPS RENAML ;TO NEXT
;
; SET FILE ATTRBUTE
;
STFATR:
MOV CL,12 ;ONLY NAME
CALL SRDRFS ;SEARCH FIRST
STFATL: ;ATTRIBUTE SET LOOP
CALL CKDREN ;CHECK END
JZ RENAMN ;END
MOV CL,0 ;FROM TOP
MOV DL,12 ;NAME PART ONLY
CALL COPYDR ;SET & WRITE DIRECTORY
CALL SRDRNX ;SEARCH NEXT
JMPS STFATL ;TO NEXT
;
; OPEN FILE
;
OPENFL:
MOV CL,15 ;WITH EXTENT
CALL SRDRFS ;SEARCH FIRST
CALL CKDREN ;CHECK NOT FOUND
OPENFN:
JZ RENAMN ;NOT FOUND END
OPENFS:
CALL EXTPNT ;GET EXTENT POINT
PUSH AX ;SAVE FILE EXTENT
PUSH BX
CALL GTDRPT ;GET DIRECTORY POINT
XCHG BX,DX
MOV BX,INPARA
MOV CL,32
PUSH DX
CALL COPY ;COPY DIRECTORY DATA TO FCB
CALL FMDRON ;INITIALIZE MODIFY MODE
POP DX
MOV BX,12
ADD BX,DX
MOV CL,[BX] ;GET FILE EXTENT
MOV BX,15
ADD BX,DX
MOV CH,[BX] ;GET RECORD COUNT
POP BX
POP AX
MOV [BX],AL ;RESTORE FILE EXTENT
CMP CL,[BX]
MOV AL,CH
JZ OPENFX ;MATCH EXTENT SO RECORD COUNT IS AVAILABLE
MOV AL,0
JC OPENFX ;UNDER
MOV AL,80H ;OVER
OPENFX:
MOV BX,INPARA
MOV DX,15
ADD BX,DX
MOV [BX],AL ;SET RECORD COUNT
OPENFE:
RET
;
; CHECK DIRECTORY MAP FOR TWO BYTE MODE
; INPUT
; BX:DESTINATION POINTER
; DX:SOURCE POINTER
;
CHKDMP:
CMP WORD PTR [BX],0
JNZ OPENFE ;SOME DATA EXIST SO NOT SET
MOV SI,DX
LODSW ;GET SOURCE DATA
MOV [BX],AX ;SET DATA
CHKDME:
RET
;
; CLOSE FILE
;
CLOSEF:
XOR AX,AX
MOV OTPARB,AL ;CLEAR RESULT PARAMETER
MOV DIRCNT,AX ;CLEAR DIRECTORY COUNT
CALL CHKROV ;CHECK R/O DISK
JNZ CHKDME ;R/O DISK SO END
CALL FMDPNT ;GET MODIFY MODE
AND AL,080H
JNZ CHKDME ;NO MODIFY MODE SO END
MOV CL,15 ;WITH EXTENT
CALL SRDRFS ;SEARCH
CALL CKDREN
JZ CHKDME ;NOT FOUND
MOV CX,16
CALL GTDRPT ;GET DIECTORY POINT
ADD BX,CX ;GET DIRECTORY MAP POINT
XCHG BX,DX
MOV BX,INPARA
ADD BX,CX ;GET FCB MAP TOP
MOV CL,16
CLOSEL: ;LOOP TO CHECK & MAKE DIRECTORY MAP
CMP DSMMOD,0
JZ CLOSED ;TWO BYTE MODE
MOV AL,[BX] ;ONE BYTE MODE GET FCB DATA
OR AL,AL
MOV SI,DX
LODSB ;GET DIRECTORY DATA
JNZ $+4 ;SOME BLOCK NUMBER EXISTS IN FCB
MOV [BX],AL ;SET TO FCB
OR AL,AL
JNZ CLOSES ;SOME DATA IN DIRECTORY
MOV AL,[BX] ;GET FCB DATA
MOV DI,DX
CLD
STOSB ;SET TO DIRECTORY
CLOSES:
CMP AL,[BX]
JNZ CLOSER ;MAP MISS MATCH
JMPS CLOSEN ;TO NEXT
;
CLOSED: ;TWO BYTE MODE
CALL CHKDMP
XCHG BX,DX
CALL CHKDMP ;CHECK & SET IF EMPTY
XCHG BX,DX
MOV SI,DX
MOV AX,[SI] ;GET DIRECTORY DATA
CMP AX,[BX] ;COMPARE WITH FCB DATA
JNZ CLOSER ;MAP MISS MATCH
INC DX
INC BX
DEC CL
CLOSEN: ;TO NEXT
INC DX
INC BX
DEC CL
JNZ CLOSEL ;TO NEXT MAP
MOV CX,-20 ;ALL MAP MATCHED & SETUPED
ADD BX,CX
XCHG BX,DX
ADD BX,CX
MOV SI,DX
LODSB
CMP AL,[BX] ;COMPARE FILE EXTENT
JC CLOSET ;DIRECTORY IS LARGER SO NOT CHANGE
MOV [BX],AL ;FCB IS LARGER SO SET EXTENT
MOV CX,3
ADD BX,CX
XCHG BX,DX
ADD BX,CX
MOV AL,[BX]
MOV DI,DX
CLD
STOSB ;SET NEW RECORD COUNT
CLOSET: ;WRITE TO DIRECTORY FOR CLOSE
MOV EXTMOD,0FFH ;SET CLOSE MODE FOR EXTENT
JMP COPYDE
;
CLOSER: ;MAP MISS MATCH ERROR
DEC OTPARB
CLOSEE:
RET
;
; GET AVAILABLE DIRECTORY
;
GTADIR:
CALL CHKROD ;CHECK R/O DISK
PUSH INPARA ;SAVE FCB POINT
MOV INPARA,OFFSET DLTFCB ;DUMMY FCB AS DELETED FCB
MOV CL,1
CALL SRDRFS ;SEARCH DELETED DIRECTORY
CALL CKDREN
POP INPARA
JZ CLOSEE ;NO DIRECTORY SPACE
MOV DX,INPARA
MOV BX,15
ADD BX,DX
MOV CL,17
XOR AL,AL
GTADIL: ;CLEAR DIRECTORY MAP & CURRENT RECORD COUNT
MOV [BX],AL
INC BX
DEC CL
JNZ GTADIL
MOV BX,13
ADD BX,DX
MOV [BX],AL ;CLEAR RECORD COUNT
CALL STDLVL
CALL COPYDA ;WRITE TO DIRECTORY
JMP FMDRON ;INITIALIZE MODIFY MODE
;
; GET NEXT DIRECTORY
;
GTNXDR:
XOR AL,AL
MOV EXTMOD,AL ;CLEAR EXTENT MODE OF CLOSE
CALL CLOSEF ;CLOSE CURRENT
CALL CKDREN
JZ CLOSEE ;CLOSE DIRECTORY NOT FOUND
MOV BX,INPARA
ADD BX,12
MOV AL,[BX] ;GET EXTENT
INC AL ;UP EXTENT
AND AL,01FH
MOV [BX],AL
JZ GTNXDX ;UP S2 EXTENT
MOV CH,AL
MOV AL,EXM
AND AL,CH
AND AL,EXTMOD
JZ GTNXDN ;TO NEXT DIRECTORY
JMPS GTNXDO ;IN SAME DIRECTORY
;
GTNXDX: ;S2 EXTENT
ADD BX,2
INC BYTE PTR [BX] ;UP S2 EXTENT
MOV AL,[BX]
AND AL,00FH
JZ GTNXDV ;OVER SO NO DATA EXIST END
GTNXDN: ;TO NEXT DIRECTORY
MOV CL,15 ;WITH EXTENT
CALL SRDRFS ;SEARCH
CALL CKDREN
JNZ GTNXDO ;OK GET
MOV AL,RWMODE
INC AL
JZ GTNXDV ;READ MODE SO FILE OVER
CALL GTADIR ;GET AVAILABLE DIRECTORY AS WRITE MODE
CALL CKDREN
JZ GTNXDV ;NO DIRECTORY SPACE
JMPS GTNXDW ;OK END
;
GTNXDO: ;OPEN BY NEW EXTENT
CALL OPENFS
GTNXDW:
CALL GTRCNT ;GET RECORD COUNT
XOR AL,AL
JMP BTPRST ;SUCCESS END
;
GTNXDV: ;FILE OVER END
CALL NODTEX ;TO NO DATA EXIST MODE
JMP FMDRON
;
; READ RECORD
;
RDNEXT: ;READ NEXT RECORD
MOV RUPCNT,1 ;SET UP COUNT
RDNEXR: ;RE RANDOM ENTRY
MOV RWMODE,-1 ;TO READ MODE
CALL GTRCNT ;GET RECORD COUNT
MOV AL,CURCNT
CMP AL,RECUNT
JC RDNEXS ;IN SAME DIRECTORY
CMP AL,080H
JNZ RDNEXV ;TOO LARGE VALUE ERROR
CALL GTNXDR ;TO NEXT DIRECTORY
CALL GTRCPT
XOR AX,AX
MOV WORD PTR CURCNT,AX
MOV [BX],AL ;CLEAR CURRENT RECORD
CMP OTPARB,0
JNZ RDNEXV ;ERROR OF DIRECTORY EXTENT
RDNEXS: ;GET IN DIRECTORY
CALL GTBLCK ;GET TARGET BLOCK
CALL CHKBLK
JZ RDNEXV ;EMPTY
CALL BLTSCT ;BLOCK NUMBER TO SECTOR
CALL TRSSET ;TO TRACK & SECTOR
CALL DREAD ;READ ONE SECTOR
JMP USRCNT ;SET RECORD COUNT TO FCB
;
RDNEXV: ;OVER OF FILE OR ERROR
JMP NODTEX
;
; WRITE NEXT RECORD
;
WTNEXT:
MOV RUPCNT,1 ;SET UP COUNT
WTNEXR: ;WRITE RANDOM ENTRY
MOV RWMODE,0 ;SET WRITE MODE
CALL CHKROD ;CHECK R/O DISK
MOV BX,INPARA
CALL CHKROL ;CHECK R/O FILE
CALL GTRCNT ;GET RECORD COUNT
MOV AL,CURCNT
CMP AL,080H
JC WTNEXS
JMP NODTEX ;FILE EXTENT ERROR
;
WTNEXS:
CALL GTBLCK ;GET BLOCK
CALL CHKBLK
MOV CL,0 ;ALLOCATED MODE FLAG
JNZ WTNEXW ;ALLOCATED BLOCK
CALL GBSDIR ;UNALLOCATED BLOCK
MOV DRBSWT,AL ;SAVE DIRECTORY BIAS
XOR CX,CX
OR AL,AL
JZ WTNEXF ;FIRST BLOCK
MOV CL,AL
DEC CX
CALL GTBLNM ;GET LAST BLOCK NUMBER
MOV CX,BX
WTNEXF:
CALL GAVLBK ;GET AVAILABLE BLOCK NUMBER
OR BX,BX
JNZ WTNEXG ;GET BLOCK
MOV AL,2
JMP BTPRST ;DISK FULL
;
WTNEXG: ;GET TARGET BLOCK
MOV TGSECT,BX ;SET BLOCK
XCHG BX,DX
MOV BX,INPARA
ADD BX,16
CMP DSMMOD,0
MOV AL,DRBSWT ;BIAS IN DIRECTORY
MOV AH,0
JZ WTNEXD ;TWO BYTE MODE
ADD BX,AX ;ONE BYTE MODE
MOV [BX],DL ;SET BLOCK NUMBER
JMPS WTNEXO
;
WTNEXD: ;TWO BYTE MODE
ADD BX,AX
ADD BX,AX
MOV [BX],DX ;SET BLOCK NUMBER
INC BX
WTNEXO:
MOV CL,2 ;UNALLOCATED MODE
WTNEXW:
CMP OTPARB,0
JZ $+3 ;OK WRITE
RET ;SOME ERROR END
;
MOV MDWRIT,CL ;SET WRITE MODE
CALL BLTSCT ;SET TRACK & SECTOR
CMP RUPCNT,2
JNZ WTNEXN ;NOT WRITE WITH ZERO FILL
CMP MDWRIT,2
JNZ WTNEXN ;NOT UNALLOCATED MODE
PUSH TGSECT ;WRITE ZERO SECTOR
MOV DI,DIRBUF
XOR AX,AX
MOV CX,64
CLD
REP STOSW ;CLEAR BUFFER
CALL STDDMA ;DMA TO WORK
MOV BX,BTSECT ;GET BLOCK TOP
WTNEXZ: ;ZERO DATA WRITE LOOP
MOV TGSECT,BX
CALL TRSSET ;SET TRACK & SECTOR
CALL DWRITE ;WRITE ZERO DATA
MOV BX,TGSECT
MOV MDWRIT,0 ;WRITE MODE TO ALLOCATED
MOV AL,BL
MOV DH,BLM
AND AL,DH
INC BX ;UP SECTOR
CMP AL,DH
JNZ WTNEXZ ;TO NEXT SECTOR
POP TGSECT
CALL STBDMA ;RESTORE DMA ADDRESS
WTNEXN:
CALL TRSSET ;TO TARGET TRACK & SECTOR
CALL DWRITE ;WRITE
MOV AL,CURCNT
MOV BX,OFFSET RECUNT
CMP AL,[BX]
JC WTNEXV ;FILE SIZE IS LARGER
MOV [BX],AL ;SETUP RECORD COUNT
INC BYTE PTR [BX]
MOV CL,2
WTNEXV:
PUSH AX
CALL FMDPNT ;GET MODIFY MODE
AND AL,07FH ;OFF NO MODIFY BIT
MOV [BX],AL
POP AX
CMP AL,07FH
JNZ WTNEXE ;RECORD COUNT IN RANGE
CMP RUPCNT,1
JNZ WTNEXE ;NOT SEQUENTIAL WRITE
CALL USRCNT ;SET RECORD COUNT TO FCB
CALL GTNXDR ;TO NEXT DIRECTORY
MOV BX,OFFSET OTPARB
MOV AL,[BX]
OR AL,AL
JNZ WTNEXA ;SOME ERROR
DEC AL
MOV CURCNT,AL ;SET CURRENT RECORD COUNT FOR UP COUNT
WTNEXA:
MOV BYTE PTR [BX],0 ;CLEAR ERROR FLAG AS CURRENT IS PRE-OPERATION
WTNEXE:
JMP USRCNT
;
; GET DIRECTORY FOR RANDOM ACCESS
; INPUT
; CL:-1 READ MODE 0 WRITE MODE
; OUTPUT
; ZF:ON OK
;
RNDDIR:
MOV RUPCNT,0 ;NO UP COUNT MODE
RNDDIS:
PUSH CX
MOV DX,INPARA
MOV BX,33
ADD BX,DX
MOV AL,[BX]
AND AL,07FH ;GET RECORD COUNT VALUE
PUSH AX
MOV AL,[BX]
RCL AL,1
INC BX
MOV AL,[BX]
RCL AL,1
AND AL,01FH ;GET EXTENT VALUE
MOV CL,AL
MOV AL,[BX]
RCR AL,1
RCR AL,1
RCR AL,1
RCR AL,1
AND AL,00FH ;GET S2 EXTENT
MOV CH,AL
POP AX
INC BX
MOV BL,[BX]
OR BL,BL
MOV BL,6 ;TOO LARGE ERROR CODE
JNZ RNDDIF ;TOO LARGE
MOV BX,32
ADD BX,DX
MOV [BX],AL ;SET CURRENT RECORD COUNT
MOV BX,12
ADD BX,DX
MOV AL,CL
SUB AL,[BX]
JNZ RNDDID ;DIFFERENT EXTENT
MOV BX,14 ;EVEN EXTENT
ADD BX,DX
MOV AL,CH
SUB AL,[BX]
AND AL,07FH
JZ RNDDIE ;EVEN ALL EXTENT
RNDDID: ;DIFFERENT EXTENT
PUSH CX
PUSH DX
CALL CLOSEF ;CLOSE CURRENT DIRECTORY
POP DX
POP CX
MOV BL,3
MOV AL,OTPARB
INC AL
JZ RNDDIU ;CANNOT CLOSE
MOV BX,12
ADD BX,DX
MOV [BX],CL ;SET TARGET EXTENT
MOV BX,14
ADD BX,DX
MOV [BX],CH ;SET TARGET S2 EXTENT
CALL OPENFL ;OPEN TARGET DIRECTORY
MOV AL,OTPARB
INC AL
JNZ RNDDIE ;OK GET
POP CX
PUSH CX
MOV BL,4
INC CL
JZ RNDDIU ;READ MODE SO UNWRITTEN EXTENT
CALL GTADIR ;WRITE MODE SO SEARCH AVAILABLE DIRECTORY
MOV BL,5
MOV AL,OTPARB
INC AL
JZ RNDDIU ;NO DIRECTORY SPACE
RNDDIE: ;GET TARGET DIRECTORY
POP CX
XOR AL,AL
JMP BTPRST
;
RNDDIU: ;ERROR END BL=ERROR CODE
PUSH BX
CALL FMDPNT
MOV BYTE PTR [BX],0C0H ;SET DIRECTORY NOT ACTIVE MODE
POP BX
RNDDIF: ;ERROR END
POP CX
MOV AL,BL
MOV OTPARB,AL ;SET ERROR CODE
JMP FMDRON
;
; READ RANDOM
;
RDRAND:
MOV CL,-1 ;REDA MODE
CALL RNDDIR ;GET DIRECTORY
JNZ RDRANE ;ERROR
CALL RDNEXR ;GET RECORD
RDRANE:
RET
;
; WRITE RANDOM
;
WTRAND:
MOV CL,0 ;WRITE MODE
CALL RNDDIR ;GET DIRECTORY
JNZ WTRANE ;ERROR
CALL WTNEXR ;WRITE ONE SECTOR
WTRANE:
RET
;
; COMPUTE FILE SIZE FROM FCB DATA
; INPUT
; BX:DIRECTORY DATA TOP
; DX:BIAS 15 RECORD COUNT 32 CURRENT RECORD
; OUTPUT
; ALCX:COUNT
;
DIRSIZ:
XCHG BX,DX
ADD BX,DX
MOV CL,[BX] ;GET RECORD COUNT
MOV CH,0
MOV BX,12
ADD BX,DX
MOV AH,[BX] ;GET EXTENT
MOV AL,0
SHR AX,1
AND AH,00FH
ADD CX,AX
MOV BX,14
ADD BX,DX
MOV AL,[BX] ;GET S2 EXTENT
MOV AH,16
MUL AH ;*16
PUSH AX
ADD CH,AL
PUSHF
POP BX
MOV AL,BL ;GET FLAG
POP BX
OR AL,BL
AND AL,1 ;GET OVERFLOW BIT
RET
;
; COMPUTE FILE SIZE BY DIRECTORY SEARCH
;
CFLSIZ:
MOV CL,12
CALL SRDRFS ;SEARCH DIRECTORY BY NAME ONLY
MOV BX,INPARA
MOV DX,33
ADD BX,DX
PUSH BX
MOV [BX],DH ;CLEAR RANDOM RECORD COUNT
INC BX
MOV [BX],DH
INC BX
MOV [BX],DH
CFLSIL: ;ONE DIRECTORY CHECK LOOP
CALL CKDREN
JZ CFLSIE ;END
CALL GTDRPT ;GET DIRECTORY POINT
MOV DX,15
CALL DIRSIZ ;GET SIZE BY RECORD COUNT
POP BX
PUSH BX
MOV DL,AL
MOV AX,CX
SUB AX,[BX]
MOV AL,DL
SBB AL,2[BX] ;COMPARE WITH CURRENT
JC CFLSIS ;SMALL SO NOT CHANGE
MOV 2[BX],DL ;SET LARGER VALUE
MOV [BX],CX
CFLSIS:
CALL SRDRNX ;SEARCH NEXT
JMPS CFLSIL
;
CFLSIE: ;END OF DIRECTORY
POP BX
RET
;
; SET RANDOM RECORD COUNT
;
STRCNT:
MOV BX,INPARA
MOV DX,32
CALL DIRSIZ ;GET SIZE BY CURRENT RECORD
MOV BX,33
ADD BX,DX
MOV [BX],CX ;SET COUNT
MOV 2[BX],AL
RET
;
; SELECT DISK
;
SELDSK:
MOV BX,LGDSKV ;LOGIN DISK VECTOR
MOV CL,CURDSK ;CURRENT DISK
ROR BX,CL
PUSH BX ;SAVE LOGIN VECTOR
XCHG BX,DX
CALL GDPTBL ;GET DISK PARAMETER
POP BX
JNZ $+5 ;OK
CALL DSEROR ;SELECT ERROR & ABORT
RCR BL,1
JC ENTRYE ;ALREADY LOGIN DISK
MOV CX,LGDSKV
CALL STDKVC ;SET LOGIN BIT
MOV LGDSKV,BX ;SAVE NEW VECCTOR
JMP INIDMP ;INITIALIZE DISK ALLOCATION MAP & CHECK SUM
;
; 14:SELECT DISK
;
MSELDK:
MOV AL,INPARB
MOV CURDSK,AL ;SET AS CURRENT DISK
JMPS SELDSK
;
; CHECK ENTRY TYPE & SELECT FOR FCB FUNCTIONS
;
ENTRYS:
CALL STWFCS ;SET FCB TO WORK FOR SEQUENTIAL ACCESS
JMPS ENTRYC
;
ENTRYR:
CALL STWFCR ;SET FCB TO WORK FOR RANDOM ACCESS
ENTRYC:
MOV BX,INPARA
MOV SYSMOD,000H
TEST BYTE PTR 8[BX],80H
JZ ENTRYM ;NOT SYSTEM MODE FILE
AND BYTE PTR 8[BX],07FH
MOV SYSMOD,60H ;USER 0 SYSTEM MODE FILE
ENTRYM:
MOV FLOMOD,-1 ;SET FCB OPERATION MODE
MOV BX,INPARA
MOV AL,[BX]
AND AL,01FH
DEC AL
MOV INPARB,AL ;SET REQUIRED DISK FOR SELECT DISK
CMP AL,01EH
JNC ENTRYD ;ZERO SO CURRENT DISK
MOV AL,CURDSK
MOV ENTDSK,AL ;SAVE DEFAULT DISK
MOV AL,[BX]
MOV ENTTYP,AL ;SAVE ENTRY TYPE
AND AL,0E0H
MOV [BX],AL ;OFF DISK ENTRY
CALL MSELDK ;SELECT DISK
ENTRYD:
MOV AL,USRCOD
MOV BX,INPARA
OR [BX],AL ;SET USER CODE
ENTRYE:
RET
;
; CHECK SYSTEM MODE & SET
;
STSYSM:
CMP SYSMOD,60H
JNZ STSYSE ;NOT USER 0 SYSTEM MODE
MOV BX,INPARA ;USER 0 SYSTEM MODE
MOV BYTE PTR [BX],0
STSYSE:
RET
;
; 13:RESET DISK SYSTEM
;
MRSDSY:
TEST SGBIOS,0FFFFH
JNZ MRSDSS ;ALREADY SET BIOS CODE SEGMENT DATA
MOV SGBIOS,CS ;SET CURRENT CODE SEGMENT
MRSDSS:
XOR BX,BX
MOV RODSKV,BX ;CLEAR R/O DISK VECTOR
MOV LGDSKV,BX ;CLEAR LOGIN DISK VECTOR
MOV BL,CURDRV
MOV CURDSK,BL ;SET CURRENT DISK
JMP SELDSK ;SELECT DISK
;
; 15:OPEN FILE
;
MOPEN:
CALL ENTRYS ;ENTRY PROCESS
CALL FMDCLR
CMP USRCOD,0
JZ MOPENS ;USER ZERO MODE SO NO SYSTEM CHECKING
MOV SYSCNT+1,00FEH ;WITH USER 0 SYSTEM MODE CHECKING
MOV SYSSRC,-1
MOPENS:
CALL OPENFL ;OPEN
CALL MOPENC ;CHECK FOUND MODE & OVERRIDE RETURN IF FOUND
TEST SYSSRC,-1
JNZ MOPENZ ;WITH USER 0 SYSTEM MODE CHECKING
MOPENE: ;NOT FOUND END
RET
;
MOPENZ: ;CHECK USER 0 SYSTEM FILE
MOV SYSSRC,0 ;CLEAR USE 0 SYSTEM MODE
CMP SYSCNT+1,00FEH
JZ MOPENE ;NO SYSTEM FILE
MOV BX,SYSCNT ;GET FILE DIRECTORY COUNT
AND BL,0FCH ;TO SECTOR TOP
DEC BX
MOV DIRCNT,BX
MOV SYSMOD,60H ;BY SYSTEM MODE
MOV BX,INPARA
MOV BYTE PTR [BX],0 ;USER 0
MOV CL,15
CALL STDRSP ;SET PARAMETER
CALL SRDRNX ;SEARCH
CALL OPENFN ;DO OPEN PROCESS
CALL MOPENC ;CHECK MODE
RET
;
MOPENC: ;CHECK OPEN MODE
CALL CKDREN
JZ MOPENE ;NOT FOUND END
POP BX ;OVERRIDING RETURN
CMP SYSMOD,60H
JNZ MOPENG ;NOT SYSTEM MODE SO SIMPLE END
MOV BX,INPARA
MOV AL,10[BX]
AND AL,080H
JNZ MOPENG ;SYSTEM FILE SO OK
MOV SYSMOD,AL ;CLEAR SYSTEM MODE AS NOT SYSTEM FILE
MOV AL,-1 ;NOT FOUND END
JMPS MRTCDS
;
MOPENG:
RET
;
; 16:CLOSE FILE
;
MCLOSE:
CALL ENTRYS ;ENTRY PROCESS
JMP CLOSEF
;
; 17:SEARCH FOR FIRST
;
MSRCHF:
CALL STWFCS ;SET FCB TO WORK
MOV BX,INDSEG
MOV SGUFCB,BX ;SAVE FCB SEGMENT
MOV CL,0
MOV BX,INPARA
CMP BYTE PTR [BX],'?'
JZ MSRCHA ;ANY DIRECTORY
CALL EXTPNT ;GET EXTENT POINT
CMP BYTE PTR [BX],'?'
JZ MSRCHX ;NO CHECK
CALL FMDCLR ;CLEAR FILE MODE
MSRCHX:
CALL ENTRYC ;DO ENTRY PROCESS
MOV CL,15
MSRCHA:
CALL SRDRFS ;SEARCH FIRST
JMPS MSRCHC ;COPY DIRECTORY DATA
;
; 18:SEARCH FOR NEXT
;
MSRCHN:
MOV BX,SGUFCB
MOV INDSEG,BX ;GET FCB SEGMENT
MOV BX,PTUFCB
MOV INPARA,BX ;GET FCB OFFSET
CALL ENTRYS ;ENTRY PROCESS
CALL SRDRNX ;SEARCH NEXT
MSRCHC:
JMP DRCOPY ;COPY DIRECTORY DATA
;
; 19:DELETE FILE
;
MDELET:
CALL ENTRYS ;ENTRY PROCESS
CALL DELDMP
JMP SDRCOD
;
; 20:READ SEQUENTIAL
;
MREADS:
CALL ENTRYS ;ENTRY PROCESS
CALL STSYSM ;CHECK & SET SYSTEM FILE MODE
JMP RDNEXT
;
; 21:WRITE SEQUENTIAL
;
MWRITS:
CALL ENTRYS ;ENTRY PROCESS
JMP WTNEXT
;
; 22:MAKE FILE
;
MMAKE:
CALL ENTRYS ;ENTRY PROCESS
CALL FMDCLR ;CLEAR FILE MODE
JMP GTADIR ;GET AVAILABLE DIRECTORY
;
; 23:RENAME FILE
;
MRENAM:
CALL ENTRYS ;ENTRY PROCESS
CALL RENAME
JMP SDRCOD
;
; 24:RETURN LOGIN VECTOR
;
MRTLIV:
MOV BX,LGDSKV ;LOGIN VECTOR
JMPS WDPRST
;
; 25:RETURN CURRENT DISK
;
MRTCDK:
MOV AL,CURDSK ;CURRENT DISK
MRTCDS:
JMP BTPRST
;
; 26:SET DMA ADDRESS
;
MSTDMO:
MOV DMAADD,DX ;DMA ADDRESS
JMP STBDMA ;SET IN BIOS
;
; 27:GET ALLOCATION MAP ADDRESS
;
MGTALM:
MOV BX,PNALMP ;ALLOCATION MAP POINT
JMPS WDPRST
;
; 29:GET R/O VECTOR
;
MGTROV:
MOV BX,RODSKV ;R/O VECTOR
JMPS WDPRST
;
; 30:SET FILE ATTRIBUTE
;
MSTFAT:
CALL ENTRYS ;ENTRY PROCESS
CALL STFATR ;SET ATTRIBUTE
JMP SDRCOD
;
; 31:GET DISK PARAMETER BLOCK ADDRESS
;
MGDPBA:
MOV BX,PNTDPB ;DISK PARAMER BLOCK POINT
;
; WORD PARAMETER SET END
;
WDPRST:
MOV OTPARA,BX
RET
;
; 32:SET/GET USER CODE
;
MSTUCD:
MOV AL,INPARB
CMP AL,0FFH
JNZ MSTUCE ;SET MODE
MOV AL,USRCOD ;GET USER CODE
JMPS MRTCDS
;
MSTUCE:
AND AL,01FH
MOV USRCOD,AL ;SET USER CODE
RET
;
; 33:READ RANDOM
;
MREADR:
CALL ENTRYR ;ENTRY PROCESS
CALL STSYSM ;CHECK & SET USER 0 SYSTEM MODE
JMP RDRAND
;
; 34:WRITE RANDOM
;
MWRITR:
CALL ENTRYR ;ENTRY PROCESS
JMP WTRAND
;
; 35:COMPUTE FILE SIZE
;
MCMPFS:
CALL ENTRYR ;ENTRY PROCESS
JMP CFLSIZ
;
; 36:SET RANDOM RECORD
;
MSTRRC:
CALL STWFCR ;SET FCB TO WORK
JMP STRCNT ;SET COUNT
;
; 37:RESET DRIVE
;
MRSTDV:
MOV AX,INPARA
NOT AX ;GET VECTOR MASK
PUSH AX
MOV BX,OFFSET LGDSKV
AND AX,[BX] ;OFF LOGIN VECTOR
MOV [BX],AX
POP AX
MOV BX,OFFSET RODSKV
AND AX,[BX] ;OFF R/O DISK
MOV [BX],AX
RET
;
; BDOS END PROCESS
;
ENDPRC:
CMP FLOMOD,0
JZ ENDPRN ;NOT FILE OPERATION
MOV BX,INPARA ;FILE OPERATION
CMP SYSMOD,060H
JNZ ENDPRS ;NOT USER 0 SYSTEM FILE
OR BYTE PTR 8[BX],80H ;SET USER 0 SYSTEM FILE MODE
ENDPRS:
MOV BYTE PTR [BX],0 ;CLEAR ENTRY TYPE
MOV AL,ENTTYP
OR AL,AL
JZ ENDPRN ;DEFAULT DISK
MOV [BX],AL ;RESTORE ENTRY TYPE
MOV AL,ENTDSK
MOV INPARB,AL ;SET DISK
CALL MSELDK ;SELECT TO DEFAULT DISK
ENDPRN:
CMP AFWFCB,-1
JNZ ENDPRW ;NOT FCB SAVED
CALL RSTFCB ;RESTORE FCB
ENDPRW:
MOV AX,OTPARA ;GET OUTPUT PARAMETER
MOV BX,AX
ENDPRE:
RET
;
; 40:WRITE RANDOM WITH ZERO FILL
;
MWRITZ:
CALL ENTRYR
MOV RUPCNT,2 ;SET COUNT TO WRITE WITH ZERO FILL MODE
MOV CL,0 ;WRITE MODE
CALL RNDDIS ;GET DIRETORY
JNZ ENDPRE ;NO DIRECTORY SPACE OR SOME ERROR
JMP WTNEXR ;WRITE
;
; 47:CHAIN PROGRAM
;
MCHAIN:
PUSH DS
MOV CX,128
MOV DI,COMBUF+2 ;CCP COMMAND BUFFER
MOV SI,DMAADD
MOV DS,DMASEG
MCHAIL: ;COMMAND COPY LOOP
LODSB
STOSB
OR AL,AL
JZ MCHAIV ;GET END
LOOP MCHAIL
MCHAIV:
MOV AL,128
SUB AL,CL ;GET LENGTH
POP DS
MOV .COMBUF+1,AL ;SET LENGTH OF COMMAND
JMP MSYRSF ;TO RESET SYSTEM
;
; 48:FLUSH BUFFERS
;
MFLUSH:
RET ;NO PROCESS IN THIS VERSION
;
DSEG
ORG 2200H
;
; DATA AREA
;
JPBIOS DW DBIOS ;BIOS CALL ROUTINE OFFSET
SGBIOS DW 0 ;BIOS CALL ROUTINE SEGMENT
;
; ERROR ROUTINE VECTORS
;
VBADSC DW EBADSC ;BAD SECTOR
VSELCT DW ESELCT ;SELECT
VRODSK DW ERODSK ;R/O DISK
VROFIL DW EROFIL ;R/O FILE
;
; WORK FOR LOAD PROGRAM
;
; GROUP DESCRIPTION BUFFER 9B * 8
; 0:FORM
; 1-2:LENGTH
; 3-4:ABSOLUTE SEGMENT
; 5-6:MINIMUM SIZE
; 7-8:MAXIMUM SIZE
;
BFGRDC RW 36
;
BFLDPR: ;PROGRAM LOADING BUFFER
RS 128
;
DGBASE DW 0 ;DATA GROUP BASE
MODE80 DB 0 ;8080 MODEL 1 OTHER 0
;
; MEMORY CONTROL BLOCK WORK
;
SYSMCB DW 0 ;M-BASE
DW 0 ;M-LENGTH
DB 0 ;M-EXTENT
;
UFCBOF DW 0 ;USER FCB OFFSET FOR FAR READ
LPSTOF DW 0 ;STACK OFFSET SAVE FOR LOAD PROGRAM FUNCTION
LPSTSG DW 0 ;STACK SEGMENT SAVE FOR LOAD PROGRAM
FMODEL DB 0 ;MODEL MODE -1 8080 0 OTHER
;
; WORK FOR CONSOLE I/O
;
ECHKIL DB 0 ;ECHO KILL MODE 0 ECHO OUT
PPROMP DB 0 ;PROMPT POSITION
PCARIG DB 0 ;CONSOLE CARRIAGE POSITION
BFCONC DB 0 ;CONSOLE INPUT CODE BUFFER
;
; WORK FOR DISK I/O
;
DLTFCB DB DELCOD ;DELETED FCB DUMMY
RODSKV DW 0 ;R/O DISK VECTOR
LGDSKV DW 0 ;LOGIN VECTOR
;
; DATA FOR DISK PARAMETERS
;
PNDRCK DW 0 ;DIRECTORY CHECK LEVEL WORK POINT
PNTRAK DW 0 ;TRACK NUMBER WORK POINT
PNSCTR DW 0 ;SECTOR NUMBER WORK POINT
;
; DISK PARAMETER HEADER COPY
;
DIRBUF DW 0 ;DIRECTORY BUFFER POINTER
PNTDPB DW 0 ;DISK PARAMETER BLOCK POINTER
PNCHSM DW 0 ;CHECK SUM AREA POINTER
PNALMP DW 0 ;ALLOCATION MAP AREA POINTER
;
; DISK PARAMETER BLOCK COPY
;
SPT DW 0 ;SECTOR / TRACK
BSH DB 0 ;BLOCK SHIFT FACTOR
BLM DB 0 ;BLOCK MASK
EXM DB 0 ;EXTENT MASK
DSM DW 0 ;DISK SIZE MAXIMUM-1
DRM DW 0 ;DIRECTORY SIZE MAXIMUM-1
ALMASK DW 0 ;ALLOCATION MAP RESERVE MASK
CHKSIZ DW 0 ;CHECKED DIRECTORY SIZE
TRKOFF DW 0 ;TRACK OFFSET
PNXTBL DW 0 ;SECTOR TRANSLATION TABLE POINT
;
; DISK WORK PARAMETERS
;
EXTMOD DB 0 ;FILE EXTENT CLOSE MODE -1 CLOSED LAST DIR
RWMODE DB 0 ;DISK READ/WRITE MODE 0 WRITE -1 READ
MDWRIT DB 0 ;WRITE MODE 0 NORMAL 1 DIRECTOR 2 UNALLOC
DIRCOD DB 0 ;DIRECTORY SEARCH CODE -1 NOT FOUND
RUPCNT DB 0 ;RECORD UP COUNT 0 RANDOM 1 SEQUENTIAL 2 WITH 0
INPARB DB 0 ;INPUT PARAMETER BYTE
DRBSWT DB 0 ;DIRECTORY BIAS FOR WRITE
DSMMOD DB 0 ;DISK SIZE MODE -1 ONE BYTE 0 TWO BYTES
FLOMOD DB 0 ;FILE OPERATION FUNCTION MODE BY FCB -1 ON
ENTDSK DB 0 ;DEFAULT DISK IN ENTRY DISK MODE
ENTTYP DB 0 ;ENTRY TYPE SAVE
RECUNT DB 0 ;RECORD COUNT
EXTENT DB 0 ;EXTENT
CURCNT DB 0,0 ;CURRENT RECORD COUNT
TGSECT DW 0 ;TARGET SECTOR OR TARGET BLOCK
BTSECT DW 0 ;BLOCK TOP SECTOR
BISDIR DB 0 ;BIAS IN DIRECTORY
DIRSCT DW 0 ;DIRECTORY SECTOR FOR CHECK SUM BIAS
FCBOFF DW 0 ;FCB OFFSET
FCBSEG DW 0 ;USER FCB SEGMENT
CURSEG DW 0 ;CURRENT SEGMENT BASE
AFWFCB DB 0 ;WORK FCB ACTIVE FLAG
CNFCBC DB 0 ;WORK FCB COPY LENGTH
;
; MEMORY MANAGEMENT WORK
;
CNTREG DB 0 ;MEMORY REGION BUFFER COUNT
SIZREG DB 0 ;MEMORY REGION TABLE SIZE
TBLREG: ;MEMORY REGION TABLE
RS 64
;
TBUMCB: ;USED MCB BUFFER AREA 5B*8
RS 40
;
CNUMCB DB 0 ;USED MCB BUFFER COUNT
PNUMCB DW 0 ;USED MCB BUFFER POINTER
SYSMOD DB 0 ;SYSTEM FILE ACCESS MODE 0 NOT 60H SYSTEM FILE
SYSSRC DB 0 ;WITH USER 0 SEARCH MODE 0 NOT
SYSCNT DW 0 ;MATCH DIRECTORY COUNT BY USER 0
SYSFLG DB 0 ;USER 0 MATCH MODE -1 USER CODE MISS SEARCH
;
; ERROR COMMENTS
;
CERROR DB 'Bdos Err On '
CERRDK DB ' : $'
CBADSC DB 'Bad Sector$'
CSELCT DB 'Select$'
CROFIL DB 'File '
CRODSK DB 'R/O$'
;
WKFCB:
RS 36 ;WORKING FCB OR MCB
;
RS 164
STACK: ;BDOS SYSTEM STACK
;
DW 0,0,0
INSTSG DW 0 ;ENTRY STACK SEGMENT
INSTOF DW 0 ;ENTRY STACK OFFSET
FLINSD DB 0 ;INSIDE FLAG FOR BDOS CALL
INPARA DW 0 ;INPUT PARAMETER WORD
OTPARA DW 0 ;OUTPUT PARAETER
INDSEG DW 0 ;ENTRY DATA SEGMENT
DB 0
;
OTPARB EQU BYTE PTR OTPARA ;OUTPUT PARAMETER AS BYTE
;
; SYSTEM DATA AREA
;
DMAADD DW 0 ;DMA OFFESET
DMASEG DW 0 ;DMA SEGMENT
CURDSK DB 0 ;CURRENT DISK
USRCOD DB 0 ;USER CODE
DIRCNT DW 0 ;DIRECTORY COUNTER
DIRCLN DB 0 ;COMPARE LENGTH FOR DIRECTORY MATCH
PTUFCB DW 0 ;USER FCB OR MCB POINT
SGUFCB DW 0 ;USER FCB SEGMENT FOR SEARCH NEXT
LSDRBF DW 0 ;LAST DIRECTORY BUFFER
MODABT DB 0 ;ABORT MODE 0 SIMPLE ABORT NO INTERNAL SETUP
DB 0
MDCONF DB 0 ;COMPLICATED I/O MODE
DB 0,0,0,0
LSTTGL DB 0 ;LIST OUT ECHO TOGGLE
CURDRV DB 0 ;CURRENT DRIVE
RS 40
;
CONWID DB 80 ;CONSOLE WIDTH
PRNWID DB 0 ;PRINTER WIDTH
CONCOL DB 0 ;CONSOLE COLUMN
PRNCOL DB 0 ;PRINTER COLUMN
;
RS 16
DB 0
;
;
END