*
*    TAPE OFF ROUTINE
*
TTOFF XRA A
 OUT TAPPT  ALL UNITS OFF
 RET
*
CTOFF EQU TTOFF  ALSO THE COMMAND
*
*
*
*     PROCESS RANDOM/SERIAL SEEK/SPACE
*
*
PRS CALL SCOMA
 RC .  NO COMMA, NO RANDOM ADDRESS
*
 CALL GCI
 CPI ','
 JZ PSS  EMPTY FIELD
 DCX H
 SHLD TXA
*
 CALL PFIXE
 XCHG
 SHLD CRSA  RANDOM SEEK ADDRESS
 MOV A,H
 ORA L
 STA RF  RANDOM FLAG
*
 CALL SCOMA  TEST FOR SPACE OPT
 RC
*
*     PROCESS SERIAL SPACE
*
PSS CALL NFIXE
 MOV A,B  B=0 FOR POS, 1 FOR NEG
 STA CSSC  FORWARD/BACKWARD FLAG
 XCHG
 SHLD CSSD
 MOV A,H
 ORA L
 STA SF  SPACED FLAG
 RZ .  RET IF NOT SPACED
 LDA RF  RANDOM FLAG
 ORA A
 JNZ ACERR  CAN'T BE SPACED AND RANDOM AT SAME TIME
 RET
*
*
*
*     FILE WRITE ONE ITEM PRIMITIVE
*
*
FLW1I LDA CACRE  CHECK ACCESS RECEIVED
 ANI 2  2=WRITE ENABLE
 JZ ACERR  ACCESS ERROR
*
 PUSH H  ADDRESS OF
 PUSH D  COUNT OF
*
 CALL FLSEK
 CALL FLSPA
 LDA RF
 MOV B,A
 LDA SF
 ORA B
 JNZ FLW1
*
FLW0 LDA CEOF  WAS LAST OPEN?
 CPI 1
 JNZ FLW1  NO
*
*  AUTOMATIC SPACE TO EOF FOR FIRST PRINT
 MVI D,-1  -1 FOR EOF
 LDA CSFID
 CALL SYS
 DB SPAOP
 JMP FLW10
 MVI A,EREOF
FLW10 CPI EREOF
 JNZ DKERR
*
*  TEST FOR RECORD OVERFLOW
FLW1 LDA CFT
 CPI BTRND  IS FILE TYPE RANDOM?
 JNZ FLW3  NOT RANDOM, NO TEST
 POP D
 PUSH D  GET SIZE OF ITEM
 INX D  ADD ONE FOR THE CR
 LHLD CRZ  WILL THIS WRITE OVERFLOW ANY REC?
 DCX H  ACCOUNT FOR THE IRG
 DCX H
 CALL HDCMP
 JC ROERR  YES, ERROR
 LHLD CREC  BYTES LEFT IN REC
 CALL HDCMP
 JNC FLW3  WON'T OVER FLOW REC
*
*  THIS WRITE WILL OVERFLOW REC, SKIP IRG AND THEN WRITE
 LDA RF  IS ACCESS RANDOM?
 ORA A
 JNZ ROERR  IT'S RANDOM, RECORD OVERFLOW!
 CALL WEOR  WRITE AN IRG
*
*  WRITE THE ITEM
FLW3 POP B  COUNT
 POP D  ADDRESS
 PUSH B
 LDA CSFID  FILE #
 CALL SYS
 DB WBLOP
 JMP DKERR
 PUSH B
*
*  TERMINATE WITH A CR
*
 LXI D,ADRCR  ADDRESS OF A CR
 LXI B,1
 LDA CSFID
 CALL SYS
 DB WBLOP
 JMP DKERR
*
 MVI A,3  LAST WAS WRITE
 STA CEOF
*
*  UPDATE CREC
 POP D  COUNT-WRITTEN
 POP H  COUNT
 LDA CFT
 CPI BTRND
 RNZ .  NOT RANDOM, NO CREC TO UPDATE
 DCX D  (THE CR)
 CALL DSUB  HL=COUNT-(COUNT-WRITTEN)=COUNT-COUNT+WRITTEN=WRITTEN
 XCHG
 LHLD CREC
 CALL DSUB  (BYTES LEFT IN RECORD)-(WRITTEN)
 SHLD CREC
 RET
*
ADRCR DB CR
*
*
*
*     FILE READ ONE ITEM PRIMITIVE
*
*
FLR1I LDA CACRE  CHECK ACCESS RECEIVED
 ANI 1  1=READ ENABLE
 JZ ACERR  ACCESS ERROR
*
 PUSH D  ADDRESS OF
*
 CALL FLSEK
 CALL FLSPA
 LDA RF  IS ACCESS RANDOM OR SPACED?
 MOV B,A
 LDA SF
 ORA B
 JNZ FLR1   RANDOM OR SPACED
*
*  TEST LAST ACCESS
 LDA CEOF
 CPI 3  FOR WRITE
 JZ ACERR  CAN'T READ AFTER A WRITE
 ANI 16-1  ANY KIND OF EOF
 CPI 6  FOR EOF
 JZ ACERR  ATTEMPT TO READ PAST EOF
*
*  DO THE READ
*
FLR1 XRA A
 STA CEOF  LAST WAS NOTHING
 POP H  ADDRESS
 MVI M,0  INCASE NOTHING IS READ (SEE FLREOF)
 XCHG .  ADDR TO DE
FLR6 PUSH D  SAVE ADDRESS
 LXI B,LINMAX  MAX LINE LENGTH
 MVI L,CR  DELIMITER
 LDA CSFID
 CALL SYS
 DB DRDOP
 JMP FLREOF
*
*  PROCESS IRG
 POP H  ADDRESS OF FIRST BYTE READ
 LDA CFT
 CPI BTRND
 JNZ FLR4  NOT RANDOM, NO IRG'S
 MOV A,M
 CPI 07FH  IRG?
 JNZ FLR4  NO
*
 XCHG .  ADDRESS BACK TO DE
 MVI A,5  EOR CODE
 STA CEOF  LAST WAS READ EOR
 JMP FLR6  KEEP READING TI'LL NON-IRG
*
*  CALC ITEM LENGTH
FLR4 LDA CEOF
 CPI 5  WAS LAST EOR?
 JZ FLR7  YES, PROCESS IT
*
 MOV D,B  BC=LINMAX-WRITTEN
 MOV E,C
 LXI H,LINMAX  HL=LINMAX
 CALL DSUB  HL=LINMAX-LINMAX+WRITTEN=WRITTEN
*
*  UPDATE CREC
 XCHG
 LDA CFT
 CPI BTRND
 JNZ FLR5  ONLY IF RANDOM
 LHLD CREC
 CALL DSUB  HL=(BYTES LEFT IN RECORD)-WRITTEN
 SHLD CREC
*
*  RETURN LENGTH
FLR5 MOV C,E  RESULT TO C
 MVI A,2
 STA CEOF  LAST WAS READ
 ORA A  Z=0, C=0  NOT EOF OR EOR
 RET .  DONE
*
*  DO EOF BUSINESS
FLREOF CPI EREOF  EOF?
 JNZ DKERR  NO, SOMETHING ELSE
 POP H  ADDR OF FIRST BYTE READ (IF ANY)
 MOV A,M
 LXI H,CEOF
 CPI 07FH  IRG?
 JNZ FLRE0  NO, MUST BE EOF
 MVI M,5  YES, EOR!
 JMP FLRE1  RETURN FLAGS
FLRE0 MVI M,6  6=LAST WAS EOF
 XRA A
 RET .  Z IS SET MEANS EOF
*
*  PROCESS EOR
FLR7 LHLD CRZ
 DCX H
 DCX H
 SHLD CREC  NEW RECORD NOW!
*
*  BACK SPACE OVER NON-IRG
 LXI B,1  BACK UP OVER CARRIAGE RETURN
 MVI D,128
 LDA CSFID
 CALL SYS
 DB SPAOP
 JMP DKERR
*
 LXI B,0FFFFH  BACK UP OVER NON-IRG
 MVI L,CR
 MVI D,128
 LDA CSFID
 CALL SYS
 DB DSPOP
 JMP DKERR   CAN'T BE BOF!!!
*
FLRE1 XRA A  Z=0
 CMC .  C=1
 RET .  Z=0 AND C=1 ==> EOR
*
*
*
*     FILE CLOSE PRIMITIVE
*
*
FLCLZ LXI H,CUFID  ZERO THE USER'S FILE ID BYTE TO SHOW CLOSED
 MVI M,0
 CALL CLOFCB  CLOSE FOR GOOD
 LDA CFT
 CPI BTRND
 CZ FLEOR  CLEAN UP RECORD IF LAST WAS WRITE
*
 LXI H,CEOF  CHECK FOR LAST WAS WRITE
 MVI A,3
 CMP M
 CZ FLEOF  END-FILE IT
*
 LDA OPEF  ONE LESS FILE OPEN
 DCR A
 STA OPEF
*
 LDA CSFID  CLOSE THE THING
 CALL SYS
 DB CLOOP
 JMP DKERR
 XRA A  C=0
 RET
*
*
*
*     FILE LOOKUP PRIMITIVE
*
*
FLLUK LXI H,LUKB  ADDR OF LOOKUP BUFFER
 LXI D,CFN  ADDR OF FILE NAME
 CALL SYS
 DB INFOP
 JMP FLL0
 XRA A  C=0 ==> FILE EXISTS, HL POINTS TO INFO BLOCK
 RET
FLL0 CPI ERNEX
 JNZ DKERR
 STC .  C=1 ==> FILE IS NONEXISTANT
 RET
*
*  FILE LOOKUP BUFFER
*
LUKB EQU $
LBFID DS 2  FILE ID
LBXB  DS 2  INDEX BLOCK ADDRESS
LBFB  DS 2  FIRST BLOCK ADDRESS
LBNB  DS 2  NUMBER OF BLOCKS IN THIS FILE
LBX1  DS 1
LBOF  DS 1  OPEN FLAG
LBX2  DS 1
LBFT  DS 1  FILE TYPE
LBBZ  DS 2  BLOCK SIZE
LBAT  DS 1  ATTRIBUTES
LBFN  DS 8  FILENAME
      DB 0
*
*
*
*     FILE OPEN PRIMITIVE      FLOPEN
*     ON CALL:
*         *** PUT SOMETHING HERE SOMEDAY ***
*     ON RETURN:
*         XA := LOG BLOCK SIZE FROM FILE IF FILE IS RANDOM
*         *** NOT COMPLETE ***
*
*
FLOC LDA CACRE  CREATE THE FILE
 ANI 2  WRITE REQUESTED?
FLOC2 MVI A,ERNEX
 JZ DKERR  NO, CANT READ FROM A NON-EXISTANT FILE
*
*  IS CREATE ENABLED?
 LDA CRT  REQUIRED TYPE HAS THE FLAG
 CPI 0FFH
 JZ FLOC2  CAN'T WRITE/READ FROM A NON-EXISTANT FILE
*
 MVI A,NATT
 STA CATTR  SET NORMAL ATTS
*
 LDA CFT
 CPI BTSCP
 JNZ FLOC1
 MVI A,CATT
 STA CATTR  SPECIAL ATTRIBUTES FOR SEMI-COMPILED PROG FILES
*
*  WELL, CREATE THE DAMN THING ... WHEOOOOO!
FLOC1 LXI D,CCREB
 CALL SYS
 DB CREOP
 JMP DKERR
*
*  THE ACTUAL ENTRY
*
FLOPEN CALL FLLUK  LOOK UP THE FILE
 JC FLOC  NOT THERE, MABY CREATE IT
*
 LHLD LBBZ  GET THE BLOCK SIZE OF THE FILE
 SHLD CBLKS  COPY IT TO THE FCB FOR RANDOM ACCESS STUFF
*
 LDA CRT
 ORA A
 JZ FLO9  TYPE CHECK DISABLED
 CPI 0FFH
 JZ FLO9  DITTO
 LXI H,LBFT  CHECK FOR TYPE CONFLICT
 CMP M
ILLT MVI A,ERITY  ILL TYPE
 JNZ DKERR
*
FLO9 XRA A
 LXI H,LBOF  LOOK AT OPEN FLAG
 MOV B,M
 DCR B  IFF IT'S ONE IT'LL BE 0 ELSE FF
 JNZ FLO0
 MVI A,WPROT  IF IT'S OPEN, WRITE PROT IT
FLO0 LXI H,LBAT
 ORA M
 STA LBAT
*
 LDA CACRE  GET ACC REQ
 CPI 3  ANY ACCESS?
 JNZ FLO4  NO
 LXI B,0  B AND C GET 0
 LDA LBAT
 MOV D,A  A AND D GET FILE'S ATTRIBS
 ANI WPROT  WRITE PROT?
 JNZ FLO2  YES, CAN'T HAVE WRITE ACCESS
 MVI B,2  GIV HIM WRITE ACC
FLO2 MOV A,D
 ANI RPROT  READ PROT?
 JNZ FLO3  YES, CAN'T GIVE READ
 MVI C,1  GIVE READ ACCESS
FLO3 MOV A,B
 ORA C  Z WILL = 1 IF NO ACCESS GRANTED
 STA CACRE  THE ACCESS RECEIVED
 MVI A,ERPRO  FILE IS PROTECTED
 JZ DKERR  IF NO ACCESS GRANTED
 JMP FLO6
*
FLO4 CPI 2  WRITE ACCESS?
 JNZ FLO5
 STA CACRE  WRITE ACCESS REC
 LDA LBAT
 ANI WPROT  MAY SET Z
 MVI A,ERPRO
 JNZ DKERR  IF PROTECTED
 JMP FLO6
*
FLO5 CPI 1  READ ACC ?
 JNZ OBERR  THEN WHAT??
 STA CACRE  READ ACCESS REC
 LDA LBAT
 ANI RPROT  MAY SET Z
 MVI A,ERPRO
 JNZ DKERR
*
*  ACTUAL OPEN
FLO6 LHLD OPEBU  STATIC BUFFERING
 LXI D,CFN  FILE NAME
 CALL SYS
 DB OPEOP
 JMP DKERR
*
 STA CSFID  THE SYSTEM'S FILE #
 MOV A,B
 STA CFT  THE FILES' REAL TYPE
*
 LDA OPEF
 INR A
 STA OPEF  ONE MORE OPEN FILE
*
 LXI H,CEOF
 MVI M,1  LAST WAS OPEN
*
*  CK FOR A RANDOM CREATE
 LDA CFT
 CPI BTRND
 RNZ .  NOT RANDOM, DONE
*
*  RANDOMIZE THE FILE
 LHLD LBXB  ALREADY RANDOM?
 MOV A,H
 ORA L
 JNZ FLO8  YES, READ IN THE LOGICAL BLOCK SIZE
 LDA CSFID  FILE#
 CALL SYS
 DB RNDOP
 JMP DKERR
 IF RANFIX
*
*  WRITE OUT THE LOG BLOCK SIZE
 LHLD CRZ
 SHLD XA  SO THEY WILL BE EQUAL
 LXI D,CRZ
 LXI B,2
 LDA CSFID
 CALL SYS
 DB WBLOP
 JMP DKERR
 RET
*
*  READ IN THE LOG BLOCK SIZE
FLO8 LXI D,XA  RETURN IT IN XA
 LXI B,2
 LDA CSFID
 CALL SYS
 DB RBLOP
 JMP DKERR
 ENDF
*
 IF RANFIX-1
FLO8 EQU $
 ENDF
 RET
*
*
*
*     EQUATES FOR FILES
*
*
FNSIZ EQU 8+2  FILE NAME LENGTH
CATT  EQU PFINF+PNAT+PATR
NATT  EQU PFINF
BTTXT EQU 86H  TEXT FILES
BTSCP EQU 85H  SEMI-COMPILED PROGRAM FILES
BTRND EQU 88H  RANDOM ACCESS FILES
BTSER EQU 87H  SERIAL ACCESS FILES
BTMAT EQU 82H  MATRIX FILES
WPROT EQU PWRI
RPROT EQU PREA
DBLKS EQU 0100H
OFTES EQU 16+1  NUMBER OF OFT ENTRIES (FCB'S) (ONE TAKEN BY...
*                                COMMANDS)
TAPPT EQU 0FAH
*
*
*     THE CURRENT FILE CONTROL BLOCK
*
COFCB EQU $  ADDRESS OF CURRENT OPEN FCB
*
CUFID DS 1  USER'S FILE ID
CSFID DS 1  SYSTEM'S FILE ID
CACRE DS 1  FILE ACCESS RECEIVED
CEOF  DS 1  FILE STATUS FLAG
CRT   DS 1  REQUIRED FILE TYPE
CRZ   DS 2  RANDOM RECORD SIZE IN BYTES
CREC  DS 2  BYTES LEFT IN CURRENT RECORD
CSSC  DS 1  SERIAL SPACE CONTROL BYTE
CSSD  DS 2  SERIAL SPACE DISTANCE
CRSA  DS 2  RANDOM SEEK ADDRESS
CCREB EQU $  ADDR OF CRTEATE BUFFER
CFT   DS 1  FILE TYPE
CBLKS DS 2  BLOCK SIZE
CATTR DS 1  ATTRIBS
CFN   DS FNSIZ+1  FILE NAME
*
OFTEZ EQU $-COFCB  OFT ENTRY SIZE
*
*
*     THE OPEN FILE TABLE
*
OFTZZ EQU OFTES*OFTEZ  THE TOTAL SIZE
OFT   DS OFTZZ  THE OPEN FILE TABLE
OFTE  DB 0FFH  END OF TABLE MARKER
*
*  MISC.
*
RF    DS 1  RANDOM FLAG
SF    DS 1  SERIAL FLAG
OFCB  DS 2  CURRENTLY OPEN FCB ADDRESS
OPEF  DB 0  NUMBER OF OPEN FILES
OPEBU DW 0  OPEN BUFFERING OPTION
*
*

