PAGE * * ******************************************* * * * * * OPEN FILE OPERATION * * * USER DE POINTS TO NAME * USER HL HAS BUFFER OPTIONS: * * IF -1 THEN UNBUFFERED * IF 0 THEN SYSTEM BUFFERED * ELSE USER BUFFERED * * * ON NORMAL RETURN, * A HAS THE FILE NUMBER * B HAS THE FILE TYPE, AND IF A=255: * * DE HAS THE DRIVER SIZE * HL HAS THE DRIVER LOAD ADDRESS * * * ERRORS: * FILE DOES NOT EXIST * NO FCBS AVAILABLE * MEMORY OVERFLOW * ILLEGAL USER BUFFER ADDRESS * * * * FIRST, LOOK UP FILE * OPEN LHLD UDE CALL SDIR JMP KIL90 DOESN'T EXIST * * FOUND, ALLOCATE FCB * LXI H,0 SHLD FRADD CALL ALFCB * * MOVE STUFF FROM DIRECTORY ENTRY TO FCB * LHLD DBUF LXI D,DETYP-DEBUF DISPLACEMENT TO TYPE DAD D XCHG . DE GETS SOURCE LXI H,FTYPE HL GETS DESTINATION CALL MOVEF DB DEFBA-DETYP+2 * LXI H,0 SHLD FNBD SET NBD=O SHLD FDLTA SET DELTA=O DCX H = -1 SHLD FAIND SET FAIND = -1 LHLD FFBA FIRST BLOCK ADDRESS SHLD FCURSC MAKE IT CURRENT BLOCK XRA A STA FFLAG CLEAR DIRTY FLAG * LXI H,DDRIV SHLD FDRIV SET DRIVER CALL OBUF JMP OPE70 UNBUFFERED * FILE IS BUFFERED CALL RBLK LOAD IN FIRST BLOCK SHLD FBDL SET BDL, (NBD=0) * OPE70 CALL LODRI SET UP DRIVER LHLD FRAD2 SHLD FRADD * * IF ALREADY OPEN, DON'T ALLOW NEW ALLOCATIONS * LHLD FID CALL SFCBS CHECK FOR OTHER FCB'S WITH SAME ID, UNIT JMP OPE75 YES JMP OPE75 YES, = 1 ALREADY JMP NRET NO, THIS WILL BE THE FIRST * * * * FILE ALREADY OPEN, SET PALO * OPE75 LDA FPROT FILE ALREADY OPEN, ORI PALO NO ALLOCATION ALLOWED. STA FPROT JMP NRET * * * CHECK FOR UNBUFFERED * OBUF LHLD UHL USER HL MOV D,H MOV E,L MAKE COPY IN DE INX D DE IS 0 IF UNBUFFERED MOV A,D ORA E ZERO TEST JZ OPE60 YES, UNBUFFERED * * CHECK FOR SYSTEM BUFFER REQUEST * MOV A,H ORA L IS IT ZERO JZ OPE40 YES, ALLOCATE SYSTEM BUFFER * * (S)HE HAS SPECIFIED A USER BUFFER * VALIDATE ADDRESS * XCHG LHLD FBLKS XCHG . DE = BLOCKSIZE, HL -> BUFFER CALL MEMCHK CHECK * OPE20 LHLD UHL * * COME HERE WITH BUFFER ADDRESS IN HL * OPE30 SHLD FBUFA SHLD TBUFA JMP RP2 RETURN CALL PLUS 2 * * * ALLOCATE SYSTEM BUFFER * OPE40 LHLD FBLKS XCHG CALL ALBUF ALLOCATE BUFFER JMP OPE30 GOT IT * * * FILE IS UNBUFFERED * OPE60 LXI H,-1 SHLD FBUFA RET * PAGE * * ****************** * * * * * ALLOCATE FILE CONTROL BLOCK * * NO PARAMETERS * * CALL ALFCB * RETURN FRADD SET, UA GETS NUMBER * ABORT IF NO FCB IS AVAILABLE * ALFCB LHLD FCBASE LXI D,FID-FCBORG DAD D FORM FID ADDRESS OF UST FCB LDA NFCB MOV C,A C = COUNT MVI B,-1 START WITH ZERO * ALF10 INR B COUNT UP MOV A,M GET ID INX H ORA M JZ ALF50 FOUND ONE LXI D,LNFCB-1 DAD D MOVE TO NEXT FCB DCR C COUNT DOWN JNZ ALF10 * * ABORT, NONE AVAILABLE * CALL ERRL1 LEVEL 1 DB FER0 * * FOUND ONE * ALF50 MOV A,B STA UA LXI D,FCBORG-FID-1 DAD D MOVE BACK SHLD FRAD2 SET ADDRESS RET * PAGE * * ***************************************** * * * * "LODRI" CHECK IF DEVICE FILE AND LOAD IF SO * LODRI LDA FTYPE GET FILE TYPE STA UB RETURN TO CALLER IN "B" INR A CHECK FOR DEVICE FILE RNZ . ASSUMPTIONS SOMETIMES PROVE OUT * * * * LOAD A DEVICE DRIVER * * * THE FILE IS A DEVICE FILE. IT'S TIME TO LOAD IT. * THE DRIVER FILE IS AN IMAGE STRUCTURED FILE WHOSE * FIRST LOAD ADDRESS IS THE DRIVER TABLE ADDRESS. * ONLY A SINGLE BLOCK IS LAODED AND,OF COURSE, THE * START ADDRESS, IF ANY, IS NOT PROCESSED. * * * LOD20 CALL PBUF PREPARE THE BUFFER AND SAVE UBC,UDE * * NOW READ THE BLOCK. THE FIRST FILE BLOCK CONTAINS * THE COUNT AND LOAD ADDRESS SO IS SPECIAL. * LHLD FBDL LXI D,-4 DAD D JNC LER2 THE FILE DOESN'T EVEN HAVE FOUR BYTES!! * SHLD LCNT LCNT=FBDL-4 LHLD TBUFA CALCUALATE SOURCE ADDESS LXI D,4 DAD D SHLD SOU SOU=TBUF+4 * * PICKUP COUNT AND LOAD ADDRESS * XCHG DCX D BACKUP TO LAST BYTE OF ADDRESS LDAX D MOV H,A SET HIGH OF ADDRESS DCX D LDAX D MOV L,A LOW OF ADDRESS SHLD UDE SET LOAD ADDRESS * * NOW GET COUNT * DCX D LDAX D MOV H,A GET H OF COUNT DCX D LDAX D MOV L,A GET L OF COUNT SHLD UBC SET BLOCK COUNT ORA H JZ LER2 ERROR--ZERO BLOCK COUNT * * SAVE SIZE, LOAD ADDRESS FOR RETURN TO THE USER * PUSH H COUNT LHLD UDE PUSH H ADDRESS XRA A STA DELFG NO DELIMITER, PLEASE! * * NOW LOOP AND MOVE THE BLOCK * LOD30 LHLD UDE DESTINATION ADDEESS SHLD DEST SET IT LHLD LCNT XCHG . DE HAS LOCAL COUNT LHLD UBC HL HAS GLOBAL COUNT CALL MBLK LHLD UBC CHECK FOR LOAD COMPLETED MOV A,H ORA L JZ LOD40 COMPLETED--COUNT NOW ZERO * * READ IN NEXT BLOCK AND SET UP TRANSFER * LHLD FBLKS CALL RDNB READ NEXT BLOCK JMP LER3 EOF, ERROR LHLD TBUFA SHLD SOU SET SOURCE TO BUFFER LHLD FBDL SHLD LCNT SET LOCAL OUNT JMP LOD30 MOVE NEXT BUFFER LOAD * * * NEXT SET THE DRIVER ADDRESS IN THE FCB AND THROW * AWAY THE BUFFER USED TO READ THE FILE. * LOD40 POP H ADDRESS WAS THE THE STACK,REMEMBER PUSH H BUT KEEP IT SHLD FDRIV CALL CLBUX CLOSE OUT BUFFER * * GET NEW BLOCK SIZE FOR DEVICE AND REPROCESS BUFFER * LHLD FDRIV LXI D,DTBLK DAD D HL POINTS TO BLOCK SIZE MOV E,M INX H MOV D,M GOT IT IN DE XCHG SHLD FBLKS SET NEW BLOCK SIZE CALL OBUF OPEN A BUFFER NOP . YES THESE ARE REQUIRED..... NOP NOP * * FINALLY SET UP THE FCB FOR USE * LXI H,0 SHLD FNBD NBD=0 SHLD FBDL BDL=0 SHLD FINDX INDEX PTR TO ZERO DCX H MINUS ONE SHLD FBACK BACK IS BOF MOV A,H STA FUNIT SET UNIT=255 LXI H,EOFCD SHLD FFORE FORE IS EOF * * SET UBC,UDE TO REPORT BACK TO CALLER * POP H FROM STACK SHLD UDE POP H AREN'T STACKS WONDERFUL SHLD UBC * * INITIALIZE THE DRIVER * CALL DVBR INITIAL ENTRY DB DTINI * RET * * * ERRORS ERRS ERS * LER2 CALL ERRL1 BAD DRIVER--ZERO COUNT DB ERZBC * LER3 CALL ERRL1 BAD DRIVER--EOF DB EREOF * ****************** * * * * DISK DRIVER INTERFACE TO SYSTEM * * DDRIV DW DDRBL READ BLOCK DW DDRNB READ NEXT BLOCK DW DDRLB READ LAST BLOCK DW DDWBR WRITE/READ BLOCK DW DDWBL WRITE BLOCK DW DDREW REWIND DW DDEOF ENDFILE DW DDCLO CLOSE DW DDSEK SEEK DW DDCTL CONTROL DW 0 BUFFER SIZE DB 0 ITO (DO NOT CHANGE) DW DDCLO INITIALIZE DDCLO RET * IDAC CALL ERRL1 ILLEGAL DRIVER OPERATION DB IDAER * PAGE * * ******************************************* * * * * * FILE READ/WRITE PROCESSER * * USER A - HAS FILE NUMBER * USER BC - HAS TRANSFER COUNT * USER DE - HAS SOURCE/DESTINATION ADDRESS * USER L - DELIMITER (IF DREAD OR DWRITE ENTRY) * * USES RWF, SOU, DEST, LCNT FOR TEMP STORAGE * * ERRORS: * * ILLEGAL FILE NUMBER * READ/WRITE PROTECTED FILE * EOF * DISK FULL * OTHER, MORE SERIOUS ERRORS * * DELIMITED READ ENTRY POINT * DREAD MVI A,-1 DEFLG GETS THIS RWF GETS 0 JMP RWP00 SET THE TWO FLAGS * * WRITE ENTRY POINT * WRITE XRA A RWP00 STA DELFG SET DELIMETER CMA . NOW INVERT THE FLAG JMP RWP02 AND SET THE READ/WRITE FLAG * * DELIMITED WRITE ENTRY POINT * DWRITE MVI A,-1 JMP RWP01 * * READ ENTRY POINT * READ XRA A =0 RWP01 STA DELFG THE DELIMITED FLAG RWP02 STA RWF THE READ/WRITE FLAG * * PREPARE FCB, ETC. * READ ENTRY POINT * CALL PFCB PREPARE THE FCB * * CHECK PROTECTION * RWCON LDA RWF ORA A JZ RWP10 READ * * CHECK AND REPORT WRITE PROTECT * CALL PROTST DB PWRI JMP RER0 ERROR - WRITE PROTECT JMP RWP20 OK * * CHECK AND REPORT READ PROTECT * RWP10 CALL PROTST DB PREA JMP RER0 ERROR - READ PROTECTION LHLD UBC XCHG . DE = COUNT LHLD UDE HL = ADDRESS CALL MEMCHK CHECK FOR WRITE INTO PROTECTED MEMORY * * PREPARE BUFFER * RWP20 CALL PBUF * SET UP TRANSFER OR RESTART AFTER NEW BUFFER LOAD RWP22 LHLD FNBD GET NEXT BYTE DISPLACEMENT XCHG LHLD TBUFA BUFFER ADDRESS DAD D HL = BUFF+NBD = SOURCE XCHG LHLD UDE = USER ADDRESS LDA RWF = READ/WRITE FLAG ORA A JZ RWP25 READ * * WRITE, INTERCHANGE SOURCE AND DEST * XCHG * RWP25 SHLD DEST SAVE DEST XCHG SHLD SOU AND SOURCE LHLD FNBD XCHG . DE MUST HAVE FNBD FOR RWP26 LHLD FBLKS = BLOCK SIZE * * IF WRITE, USE BLOCKSIZE AS BDL, ELSE BDL * JNZ RWP26 LHLD FBDL * * DE HAS NBD, HL HAS BDL OR BLOCK SIZE * COMPUTE HL-DE AS LOCAL COUNT * RWP26 CALL ARITH HL=HL-DE SHLD LCNT SAVE LOCAL COUNT XCHG . DE HAS LOCAL COUNT * * TEST IF COUNT IS ZERO (DE HAS LCNT) * RWP30 LHLD UBC MOV A,H ORA L JZ RWP70 YES, COUNT IS 0 --DONE * * SEE IF DELIMITER SEEN * LDA DELFG DCR A JZ RWP70 YES!, STOP TRANSFER * * TEST IF LOCAL COUNT IS ZERO * MOV A,D ORA E JNZ RWP50 NON-ZERO, MOVE DATA * * LOCAL COUNT IS ZERO * CALL UPBDL UPDATE BDL LDA RWF ORA A READ OR WRITE? JNZ RWP40 WRITE * READ LHLD FBLKS READ CALL RDNB READ NEXT BLOCK JMP EOFER EOF HIT JMP RWP22 CONTINUE THE READ * * * WRITE * RWP40 LHLD FBDL CALL WDBR WRITE BLOCK JMP RWP22 AND ONWARD * * * COUNT IS ZERO, OPERATION IS COMPLETE * UPDATE BDL IF NECESSARY * * WE CAN ALWAYS CALL FDB EVEN IF OPER=READ * IF WE ASSUME READ DIDN'T SET DIRTY * RWP70 CALL UPBDL CALL FDB YES, FLUSH DEVICE BUFFER CALL RBUF RELEASE BUFFER JMP NRET NORMAL RETURN WHEN DONE * * * UPDATE BDL * UPBDL LHLD FBDL XCHG LHLD FNBD CALL COMP CHECK BDL AND NBD RNC . BDL GE NBD SHLD FBDL UPDATE BDL RET * * * SET DIRTY IF WRITING * RWP50 CALL MBLK LHLD LCNT XCHG . DE GETS NEW LOCAL COUNT FOR LATER LDA RWF ORA A JZ RWP30 NOT WRITE STA FFLAG IT'S WRITE SET DIRTY FLAG JMP RWP30 * ********************* * * CALCULATE HL = HL-BC * RWPS MOV A,L SUB C MOV L,A MOV A,H SBB B MOV H,A RET * * * CALCULATE HL = HL-DE * ARITH MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A RET ***************************************** * * * CHECK FOR READ OR BUFFER IN PROTECTED AREAS * * ON CALL HL HAS START ADDRESS * DE HAS COUNT * * ON RETURN, ALL REGISTERS DESTROYED; ABORT IF ERROR * MEMCHK DCX D LOWER COUNT FOR PROPER TESTS PUSH D SAVE COUNT LXI D,SYSTOP TOP OF SYSTEM CALL COMP DO COMPARE POP D JNC MEMC0 IF START ADDRESS LESS THAN TOP OF SYSTEM * * START IS ABOVE SYSTEM. OK IF IT DOESN'T PASS ZER0 * DAD D HL= TOP OF WRITE MOV A,H GET HIGH BYTE ORA A RM . STILL MINUS....OK * MERR1 CALL ERRL1 DB MPE0 USER MEMORY PROTECT ERROR * MEMC0 PUSH H ADDRESS PUSH D COUNT DAD D HL GETS HIGEST USED ADDRESS XCHG . TO DE LHLD LOWAD GET LOWEST SYSTEM ADDRESS CALL COMP POP H COUNT TO HL POP D START ADDRESS MOV B,H MOV C,L SAVE COUNT IN BC JC MEM10 DE .LT. LOWAD OK STILL * * ATTEMPTING TO WRITE INTO SYSTEM..SEE IF CBUF * LXI H,CBUF CALL COMP DE HAS WRITE ADDRESS JNZ MERR2 IF IT WASN'T CBUF * * NOW TEST COUNT FOR 256 OR LESS * LXI H,-256 DAD B BC = COUNT RNC . IF COUNT .LT. 256 * MERR2 CALL ERRL1 DB MPE1 SYSTEM MEMORY PROTECT * * * SEE IF ABOVE USER PROTECT * MEM10 LHLD UPROT DE HAS MEMORY WRITE START CALL COMP RNC . HL .GE. DE (START <= UPROT ), OK JMP MERR1 USER MEMORY PROTECT * *