% *************************************************************************** % ** COPYRIGHT (C) MASSACHUSETTS INSTITUTE OF TECHNOLOGY AND HARVARD ** % ** UNIVERSITY, BIOMEDICAL ENGINEERING CENTER 1977. ALL RIGHTS RESERVED. ** % *************************************************************************** % 8080 FILE SYSTEM % DISK VERSION FOR CP/M BIOS USING AN ADAPTED VERSION OF THE TAPE SYSTEM % J. SACHS 3/7/77 % ADDITIONS BY A.R.M.CLARKE, CHILTON COTTAGE, CHILTON CORNER, SUDBURY, SUFFOLK % 11/8/80 % THIS IS AN ALTERED VERSION OF THE FILE HANDLING SYSTEM FOR THOSE WHO WISH % TO USE THE ORIGINAL STOIC SYSTEM. IT WAS DEVELOPED ON A SINGLE DRIVE SYSTEM. % TO USE IT ONE LOADS THE KERNEL IN THE NORMAL WAY AND THEN LOADS THIS AND % ANY OTHER MODULES THAT ONE NEEDS (PARTICULARLY THE EDITOR.) WHEN ALL IS % SAFELY GATHERED IN, THEN TYPE THE WORD "START"(WITHOUT THE PARENTHESES) % AND THE FILE SYSTEM SHOULD BE ACTIVATED. IF YOU EVER WANT TO DO ANOTHER % CPMLD THEN TYPE "FINISH" (AGAIN WITHOUT PARENTHESIS). INSERT YOUR STOIC % DISK WHICH WOULD NOT NEED CP/M ON IT (A PLAIN FRESH DISK TO START WITH!) % AND OFF YOU GO. I HAVE TESTED AND HOPEFULLY DEBUGGED THIS SYSTEM BUT % PLEASE BEAR IN MIND THAT THIS IS, IN FACT A MODIFICATION OF THE TAPE % RATHER THAN THE DISK STOIC FILE SYSTEM: THIS MIGHT EXPLAIN ONE OR TWO % MINOR BUGS THAT I HAVEN'T ELIMINATED (OCCASIONAL LOSS OF 1ST DIRECTORY % ENTRY SOLVED BY PUTTING IN A DUMMY NULL FILE THERE; TROUBLE WITH SAVING % AND RESTORING THE CORE IMAGE). ALL IN ALL A GOOD SYSTEM WITH THE ADVANTAGE % OF SPEED BUT THE DISADVANTAGE OF HAVING ONLY ONE FILE OF UNDECLARED SIZE % OPEN FOR WRITING AT ANY ONE TIME. % AS YOU WILL SEE, THIS VERSION OF THE FILE SYSTEM USES ONLY % BIOS CALLS, LIKE THE STOIC IN THE U.S.CP/MU.G. LIBRARY. YOU CAN THEREFORE % OVERWRITE THE FDOS UP TO THE BIOS JUMP TABLE IF YOU WISH (RESET THE STOIC % MEMORY VARIABLE). % THE PATCHES POKE THE NEW DISKIN AND DISKOU SUBROUTINE % ADDRESSES INTO THE KERNEL. IF YOU ALTER YOUR KERNEL CHECK THAT THESE % LOCATIONS ARE STILL CORRECT. I AM BUSILY REWRITING THE KERNEL TO CPMIFY % IT PROPERLY, SO I HAVEN'T GIVEN THIS PROGRAM THE ATTENTION IT DESERVES. % I HAVE MADE THE CODE IN MY PATCH CLEAR RATHER THAN COMPACT. IF YOU FIND % A BUG OR AN IMPROVEMENT LET ME KNOW! THE PATCH IS SET UP FOR SINGLE % SIDED SINGLE DENSITY 8IN DRIVE. IF YOU DON'T HAVE THIS THEN GOD BLESS % YOU, YOU MUST ALTER IT TO SUIT. IT ALSO ASSUMES CP/M 1.4, SO WATCH IT! RADIX @ DECIMAL % ADDRESS BLOCK-NUMBER NUMBER-OF-BLOCKS RDBLKS % READS BLOCKS DIRECTLY FROM MASS STORAGE DEVICE INTO MEMORY 'RDBLKS CODE< B POP, H POP, UNIT LDA, A ORA, RAL, H ORA, A H MOV, D POP, (READ) CALL, NEXT JMP, > % ADDRESS BLOCK-NUMBER NUMBER-OF-BLOCKS WRBLKS % WRITES BLOCKS DIRECTLY FROM MEMORY TO THE MASS STORAGE DEVICE 'WRBLKS CODE< B POP, H POP, UNIT LDA, A ORA, RAL, H ORA, A H MOV, D POP, (WRITE) CALL, NEXT JMP, > % BLOCK-NUMBER BLIST DISPLAYS THE REQUESTED BLOCK (IN FORTH FORMAT ) 'BLIST : DUP "BLOCK NO." MSG = CR RBLOCK 0 SWAP DUP 1024 + SWAP DO DUP <#> 3 OVER - SPACES TYPE 1+ SPACE I 64 TYPE CR 64 +LOOP DROP ; % CONSTANTS AND VARIABLES 4 'EOF CONSTANT % END OF FILE CODE 26 'NSECTORS CONSTANT % NUMBER OF SECTORS TO A TRACK 77 'NTRACKS CONSTANT % NUMBER OF TRACKS TO A DISK 128 'NBYTES CONSTANT % NUMBER OF BYTES TO A SECTOR 8 'NSECS/BLOCK CONSTANT % NUMBER OF SECTORS TO A BLOCK NTRACKS NSECTORS * NSECS/BLOCK / 'NBLKS CONSTANT % # OF BLOCKS ON MASS STORAGE DEVICE NSECS/BLOCK NBYTES * 'BSIZE CONSTANT % # OF BYTES PER BLOCK 0 'FCT VARIABLE % FILE CONTROL TABLE POINTER 0 'ENTP0 VARIABLE % 2 TEMPORARY VARIABLES 0 'ENTP1 VARIABLE 4 'BDMA ARRAY % BIOS PARAMETER VARIABLES BDMA 2 + 'BDRIVE CONSTANT BDRIVE 1+ 'BSECTOR CONSTANT BDRIVE 2 + 'BTRACK CONSTANT BDRIVE 3 + 'BNSECS CONSTANT HEX 011F 'DSKOUAD CONSTANT % DEPENDANT ON VERSION OF CORE IMAGE 0122 'DSKINAD CONSTANT % DITTO DECIMAL % IN THE FOLLOWING CODE I HAVE ADDED NO SKEW FACTOR AT ALL SO AS TO KEEP % THINGS SIMPLE. IT SEEMS FAST ENOUGH WITHOUT IT BUT FEEL FREE TO ADD IT % TO TASTE! ASSEMBLER< . 1 LHLD, D DAD, PCHL, 'BIOS CONSTANT . "OFF THE DISK!" S, H LXI, ERROR JMP, 'INCSNDECS CONSTANT . B PUSH, XCHG, BDMA SHLD, NSECS/BLOCK H LXI, MUL CALL, NSECTORS B LXI, DIV CALL, H INX, L D MOV, UNIT LDA, BDRIVE H LXI, A M MOV, H INX, D M MOV, H INX, E M MOV, H POP, H DAD, H DAD, H DAD, BNSECS SHLD, RET, 'SETUP CONSTANT . BDMA H LXI, M C MOV, H INX, M B MOV, H PUSH, 33 D LXI, BIOS CALL, H POP, H INX, M C MOV, 24 D LXI, H PUSH, BIOS CALL, H POP, H INX, M C MOV, 30 D LXI, H PUSH, BIOS CALL, H POP, H INX, M C MOV, 27 D LXI, BIOS CALL, RET, 'TELLBIOS CONSTANT . SETUP CALL, . TELLBIOS CALL, 36 D LXI, BIOS CALL, RNZ, INCSNDECS CALL, JNZ, RET, 'DSKIN CONSTANT . SETUP CALL, . TELLBIOS CALL, 39 D LXI, BIOS CALL, RNZ, INCSNDECS CALL, JNZ, RET, 'DSKOU CONSTANT > HEX 'START : C3 DSKOUAD B! C3 DSKINAD B! DSKIN DSKINAD 1+ ! DSKOU DSKOUAD 1+ ! ; 'FINISH : 3E DSKOUAD B! 06 DSKINAD B! C901 DSKOUAD 1+ ! C508 DSKINAD 1+ ! ; OCTAL % DEFINE FILE CONTROL TABLE VARIABLES 'FCTBLK0 CODE< FCT LHLD, PUSH JMP, > 'FCTUNIT CODE< 2 D LXI, . . FCT LHLD, D DAD, PUSH JMP, > 'FCTBLK CODE< 4 D LXI, JMP, > 'FCTBYTE CODE< 6 D LXI, JMP, > % GET ADDRESS OF DIRECTORY BUFFER 'DIRECTORY : 0 RBLOCK ; % GET NEXT DIRECTORY ENTRY 'NXENT0 : DIRECTORY 10 - ENTP0 ! ; 'NXENT : 10 ENTP0 +! ENTP0 @@ ; % GET STARTING BLOCK # GIVEN PTR TO DIRECTORY ENTRY 'SBLK : 6 + @ 777 AND ; % FILENAME MATCH 'MATCH CODE< B POP, H POP, 6 E MVI, . B LDAX, M CMP, 0PUSH JNZ, A ORA, -1PUSH JZ, B INX, H INX, E DCR, JNZ, -1PUSH JMP, > % SEARCH FOR MATCH IN DIRECTORY 'SEARCH : NXENT0 BEGIN NXENT IF ENTP0 @ OVER 1+ MATCH IF DROP ENTP0 @ -1 -1 ELSE 0 THEN ELSE DROP 0 -1 THEN END ; % TEST IF FILE EXISTS 'EXIST : SEARCH NOT IF "FILE DOES NOT EXIST" ERR THEN ; % TEST IF FILE DOES NOT EXIST 'NOT-EXIST : SEARCH IF "FILE ALREADY EXISTS" ERR THEN ; % GET PTR TO LAST DIRECTORY ENTRY 'SLOT : DIRECTORY BEGIN DUP @ IF 10 + REPEAT ; % TEST IF FILE IS OPEN 'OPEN? : FCTBLK0 EQZ FCTBLK0 @ EQZ OR IF "FILE NOT OPEN" ERR THEN ; % GET FILE POSITION 'GPOS : OPEN? FCTBLK @ BSIZE UM* FCTBYTE @ M+ ; % SET FILE POSITION 'SPOS : OPEN? BSIZE UM/MOD FCTBYTE ! FCTBLK ! ; % INITIALIZE DIRECTORY 'ZERO-DIRECTORY : DIRECTORY BSIZE 2/ 0FILL 1 DIRECTORY 6 + ! UPDATE ; % SQUASH DELETE ENTRIES FROM END OF DIRECTORY 'FSQUASH : SLOT BEGIN DUP DIRECTORY NE SWAP 10 - DUP @ -1 EQ 2SWAP AND IF DUP 3 0FILL UPDATE REPEAT DROP ; % DELETE FILE 'DELETE : EXIST -1<- UPDATE FSQUASH ; % RENAME FILE 'RENAME : DUP NOT-EXIST 1+ SWAP EXIST 6 MVBYTES UPDATE ; % CREATE CONTIGUOUS FILE 'CCONT : OVER NOT-EXIST SLOT DUP DIRECTORY BSIZE 10 - + LT IF SWAP OVER SBLK + DUP NBLKS GE IF "DISK FULL" ERR THEN OVER 16 + ! DUP 10 + 3 0FILL SWAP 1+ SWAP 6 MVBYTES ELSE "DIRECTORY FULL" ERR THEN UPDATE ; % DEFINE FILE CONTROL TABLE 'FILE : 4 SWAP ARRAY ;CODE< XCHG, FCT SHLD, NEXT JMP, > % COMPUTE # OF BLOCKS LEFT ON STORAGE DEVICE 'LEFT : NBLKS SLOT SBLK - ; % LIST FILENAME 'LIST-NAME : DUP 6 + SWAP DO I B@ DUP IF TYO ELSE DROP EXIT THEN LOOP ; % LIST DIRECTORY 'LIST-DIRECTORY : IFCR NXENT0 BEGIN NXENT ENTP0 @ SBLK U<#> 4 OVER - SPACES TYPE SPACE IF ENTP0 @@ -1 EQ IF "(--)" 1+ ELSE ENTP0 @ THEN LIST-NAME 0 ELSE -1 THEN COLUMN B@ 16 GT IF CR ELSE 16 TAB THEN END ; % OPEN FILE 'OPEN : EXIST SBLK FCTBLK0 ! UNIT B@ FCTUNIT ! FCTBLK 0<- FCTBYTE 0<- ; % CLOSE FILE 'CLOSE : FCTBLK0 0<- ; % OPEN FOR WRITING 'WOPEN : DUP SEARCH IF DROP DUP DELETE THEN DUP LEFT 1- DUP LEZ IF "DISK FULL" ERR THEN CCONT OPEN ; % GIVE BACK UNUSED BLOCKS 'SHRINK : OPEN? FCTBLK0 @ FCTBLK @ + FCTBYTE @ NEZ - SLOT 6 + ! UPDATE ; % EXECUTE A FILE 'LOAD : EXIST SBLK LOAD ; ASSEMBLER< DEFINITIONS % GET NEXT BYTE FROM FILE . H LXI, ERROR JMP, '(GETBYTE) CONSTANT % PUT NEXT BYTE IN FILE . PSW PUSH, FCT LHLD, H A MOV, L ORA, IFZ, M E MOV, H INX, M D MOV, D A MOV, E ORA, IFZ, H INX, M A MOV, H INX, A ORA, RAL, D ORA, A D MOV, H INX, M C MOV, H INX, M B MOV, H INX, XCHG, B DAD, XCHG, H PUSH, (RBLOCK) CALL, H POP, M C MOV, H INX, M B MOV, XCHG, B DAD, H PUSH, XCHG, B INX, C A MOV, BSIZE 400 MOD CPI, IFNZ, B A MOV, BSIZE 400 / CPI, IFNZ, H DCX, H DCX, H DCX, M INR, IFNC, H INX, M INR, H DCX, THEN, H INX, H INX, H INX, 0 B LXI, THEN, THEN, B M MOV, H DCX, C M MOV, H POP, PSW POP, A M MOV, NEWEST LHLD, 6 D LXI, D DAD, -1 M MVI, H INX, -1 M MVI, RET, THEN, THEN, L> H LXI, ERROR JMP, '(PUTBYTE) CONSTANT > DEFINITIONS 'GETBYTE CODE< (GETBYTE) CALL, A L MOV, 0 H MVI, PUSH JMP, > 'PUTBYTE CODE< H POP, L A MOV, (PUTBYTE) CALL, NEXT JMP, > % GET NEXT N BYTES 'GETBYTES CODE< H POP, D POP, H A MOV, A ORA, NEXT JM, L ORA, NEXT JZ, . D PUSH, H PUSH, (GETBYTE) CALL, H POP, D POP, D STAX, D INX, H DCX, H A MOV, L ORA, JNZ, NEXT JMP, > % PUT NEXT N BYTES 'PUTBYTES CODE< H POP, D POP, H A MOV, A ORA, NEXT JM, L ORA, NEXT JZ, . D PUSH, H PUSH, D LDAX, (PUTBYTE) CALL, H POP, D POP, D INX, H DCX, H A MOV, L ORA, JNZ, NEXT JMP, > % PUSH THE # OF BLOCK OF FREE MEMORY (ERROR IF 0) 'MAXBL : MEMORY @ . - BSIZE / DUP EQZ IF "INSUFFICIENT MEMORY" ERR THEN ; % BLK1 BLK2 NBLKS MVBLOCKS % MOVES NBLKS BLOCKS FROM BLK1 TO BLK2 'MVBLOCKS : DUP 0 DO . 3OVER I + 2OVER MAXBL MIN RDBLKS . 2OVER I + 2OVER MAXBL MIN WRBLKS MAXBL - MAXBL +LOOP 3DROP ; % SQUASH THE DIRECTORY 'SQ : ENTP0 @ SBLK ENTP1 @ SBLK ENTP0 @ 10 + SBLK ENTP0 @ SBLK - MVBLOCKS ENTP1 @ SBLK ENTP0 @ SBLK - DUP ENTP0 @ 10 + SBLK + SWAP ENTP0 @ 6 + +! ENTP0 @ ENTP1 @ 10 MVBYTES ENTP1 @ 10 + 3 0FILL ENTP1 @ 16 + ! 10 ENTP1 +! ; 'SQUASH : FLUSH FSQUASH NXENT0 BEGIN NXENT 1+ U2/ EQZ END ENTP0 ENTP1 MOVE ENTP0 @@ IF BEGIN BEGIN NXENT 1+ END ENTP0 @@ IF SQ UPDATE 0 ELSE -1 THEN END THEN FLUSH ; % READ AND WRITE CORE IMAGE '(RDCI) CODE< D POP, 4 H LXI, SP DAD, T1 SHLD, B POP, H POP, T1 2+ SHLD, MEMORY LHLD, SPHL, T1 2+ LHLD, UNIT LDA, A ORA, RAL, H ORA, A H MOV, (READ) CALL, . HEX T1 LHLD, SPHL, 0006 LHLD, MEMORY SHLD, NEXT JMP, > '(RESTART) CONSTANT '(WRCI) CODE< D POP, 4 H LXI, SP DAD, T1 SHLD, B POP, H POP, T1 2+ SHLD, MEMORY LHLD, SPHL, T1 2+ LHLD, UNIT LDA, A ORA, RAL, H ORA, A H MOV, (WRITE) CALL, T1 LHLD, SPHL, NEXT JMP, > OCTAL 'RDCI : EXIST DUP SBLK SWAP 10 + SBLK OVER - STATE (RDCI) ; 'WRCI : SLOT SBLK SWAP . STATE - BSIZE U/MOD NEZ - SWAP OVER CCONT FLUSH STATE (WRCI) ; HEX % WRITE BOOTSTRAP FILE 'WRITE-BOOT : SLOT SBLK DUP WBLOCK DUP 0 <- 2+ (RESTART) <- 1+ SWAP . 0 - BSIZE U/MOD NEZ - SWAP OVER 1+ CCONT FLUSH EBUF 0 (WRCI) ; OCTAL % DEFINE TWO FILE CONTROL TABLES 'IFILE FILE 'OFILE FILE % TYPE A FILE 'PRINT : IFILE OPEN BEGIN GETBYTE DUP EOF NE IF TYO REPEAT DROP CLOSE ; % COPY A FILE 'XFER : OFILE WOPEN IFILE OPEN BEGIN IFILE GETBYTE DUP OFILE PUTBYTE EOF EQ END IFILE CLOSE OFILE SHRINK CLOSE ; RADIX ! ;F ***EOF***