;BIOS3.ASM FOR MORROW DISK JOCKEY VER 16 NOV 94 ************************************************************* * * * BIOS AND LOADER BIOS FOR CP/M 3.0 (BETA V1.2) FOR DJ2D * * CONTROLLER. * * WRITTEN NOVEMBER 1982 BY DAVE HARDY AND KEN JACKSON * * * ************************************************************* TITLE 'BIOS AND LOADER BIOS FOR CP/M 3.0' ************************************************************* * * * TO INSTALL THIS BIOS INTO CP/M 3.0, PERFORM THE FOLLOWING * * STEPS: * * 1. ADD YOUR OWN CONSOLE AND PRINTER I/O TO THIS FILE* * AT CONIN:, CONOUT:, CONST:, LIST:, AND LISTST: * * 2. ADD ANY INITIALIZATION THAT YOU NEED AT TINIT: * * 3. SET THE LDRBIOS EQUATE IN THIS FILE TO TRUE * * 4. RMAC SCB (ASSEMBLE SCB.ASM, SUPPLIED) * * 5. RMAC BIOS3 (ASSEMBLE LDRBIOS) * * 6. REN LDRBIOS.REL=BIOS3.REL * * 7. SET THE LDRBIOS EQUATE IN THIS FILE FALSE * * 8. RMAC BIOS3 (ASSEMBLE BIOS) * * 9. LINK BIOS3[B]=BIOS3,SCB * * 10. GENCPM * * (ANSWER ALL QUESTIONS WITH A CARRIAGE RETURN * * EXCEPT ANSSWER "N" AT "BANK SWITCHED MEMORY?" * * QUESTION, AND ANSWER WITH YOUR TOP PAGE OF * * MEMORY WHEN ASKED "TOP PAGE OF MEMORY?") * * 11. LINK CPMLDR[L100]=CPMLDR,LDRBIOS * * 12. CPMLDR (LOAD AND RUN CP/M 3.0) * * * ************************************************************* FALSE EQU 0 ;DEFINE TRUE AND FALSE TRUE EQU NOT FALSE ************************************************************* * * * THE FOLLOWING REVISION NUMBER IS IN REFERENCE TO THE CP/M * * 3.0 CBIOS. * * * ************************************************************* REVNUM EQU 10 ;BIOS REVISION NUMBER CPMREV EQU 30 ;CP/M REVISION NUMBER ************************************************************* * * * THESE ARE THE ROUTINES CALLED FROM THE DJ2D'S BUILT-IN * * EPROM. (MODEL B ONLY) * * * ************************************************************* ORIGIN EQU 0E000H ;EPROM ORIGIN OF YOUR DJ2D BOARD DJRAM EQU ORIGIN+400H ;RAM ADDRESS DJHOME EQU DJRAM+9H ;DJ2D TRACK ZERO SEEK DJTRK EQU DJRAM+0CH ;DJ2D TRACK SEEK ROUTINE DJSEC EQU DJRAM+0FH ;DJ2D SET SECTOR ROUTINE DJDMA EQU DJRAM+012H ;SET DMA ADDRESS DJREAD EQU DJRAM+15H ;READ ROUTINE DJWRITE EQU DJRAM+18H ;WRITE ROUTINE DJSEL EQU DJRAM+1BH ;DJ2D SELECT DRIVE ROUTINE DJSTAT EQU DJRAM+27H ;STATUS ROUTINE DJSIDE EQU DJRAM+30H ;SET SIDE ROUTINE ************************************************************* * * * MISCELLANEOUS INTERNAL BIOS EQUATES. * * WE'VE TRIED TO MAINTAIN COMPATIBILITY WITH THE MORROW'S * * DJ2D BIOS. * * * ************************************************************* LDRBIOS EQU FALSE ;TRUE IF YOU WANT TO ASSEMBLE AS LOADER BIOS UD2 EQU FALSE ;TRUE IF WANT TO USE USER/DRIVE BYTE @ ADDR 4 CDISK EQU 4 ;ADDRESS OF LAST LOGGED DISK BUFF EQU 80H ;DEFAULT BUFFER ADDRESS TPA EQU 100H ;TRANSIENT MEMORY ENTRY EQU 5 ;BDOS ENTRY JUMP ADDRESS RETRIES EQU 10 ;MAX RETRIES ON DISK I/O BEFORE ERROR ACR EQU 0DH ;CARRIAGE RETURN ALF EQU 0AH ;A LINE FEED MAXDISK EQU 4 ;MAX OF DISK DRIVES CLEAR EQU 1AH ;CLEAR SCREEN CODE FOR LDRBIOS ************************************************************* * * * PUBLIC AND EXTERNAL DECLARATIONS REQUIRED FOR CP/M PLUS. * * * ************************************************************* CSEG PUBLIC ?BOOT,?WBOOT,?CONST,?CONIN,?CONO,?LIST,?AUXO,?AUXI PUBLIC ?HOME,?SLDSK,?STTRK,?STSEC,?STDMA,?READ,?WRITE PUBLIC ?LISTS,?SCTRN PUBLIC ?CONOS,?AUXIS,?AUXOS,?DVTAB,?DEVIN,?DRTBL,?MLTIO,?FLUSH PUBLIC ?MOV,?TIM,?BNKSL,?STBNK,?XMOV IF NOT LDRBIOS PUBLIC ?INIT,?LDCCP EXTRN @CIVEC,@COVEC,@AIVEC,@AOVEC,@LOVEC,@MXTPA ENDIF ;NOT LDRBIOS ************************************************************* * * * THE BIOS JUMP TABLE * * * * THE JUMP TABLE BELOW MUST REMAIN IN THE SAME ORDER, THE * * ROUTINES MAY BE CHANGED, BUT THE FUNCTION EXECUTED MUST BE* * THE SAME. THERE ARE 33 JUMPS IN THE CP/M PLUS BIOS VECTOR* * * ************************************************************* ; ?BOOT: JMP CBOOT ;COLD START ENTRY POINT WBOOTE: ?WBOOT: JMP WBOOT ;WARM START ENTRY POINT ?CONST: JMP CONST ;CONSOLE STATUS A=FF=READY ?CONIN: JMP CONIN ;CONSOLE INPUT DATA IN A COUT: ?CONO: JMP CONOUT ;CONSOLE OUTPUT DATA IN C ?LIST: JMP LIST ;LIST DEVICE DATA IN C ?AUXO: JMP AUXOUT ;PUNCH DEVICE NONE ?AUXI: JMP AUXIN ; READER DEVICE NONE ?HOME JMP HOME ;SEEK HOME TRACK ?SLDSK: JMP SETDRV ;SELECT DISK DISK IN C ?STTRK: JMP SETTRK ;SEEK TRACK TRACK IN BC ?STSEC: JMP SETSEC ;SET SECTOR SECTOR IN BC ?STDMA: JMP SETDMA ;SET DMA DMA IN BC ?READ: JMP READ ;READ SECTOR ?WRITE: JMP WRITE ;WRITE SECTOR ?LISTS: JMP LISTST ;RETURN LIST STATUS A=FF=READY ?SCTRN: JMP SECTRAN ;SECTOR TRANSLATE SECTOR IN BC ?CONOS: JMP CONOST ; OUTPUT STATUS OF CONSOLE ?AUXIS: JMP AUXIST ; INPUT STATUS OF AUX. PORT ?AUXOS: JMP AUXOST ; OUTPUT STATUS OF AUX. PORT ?DVTAB: JMP DEVTBL ; ADDRESS OF CHAR. I/O TABLE ?DEVIN: JMP DEVINI ;INITIALIZE CHAR. I/O DEVICES ?DRTBL: JMP DRVTBL ; ADDRESS OF DISK DRIVE TABLE ?MLTIO: JMP MULTIO ;SET NUMBER OF LOGICALLY CONSECUITIVE ;SECTORS TO BE READ OR WRITTEN ?FLUSH: JMP FLUSH ;FORCE PHYSICAL BUFFER FLUSHING FOR ;USER-SUPPORTED DEBLOCKING ?MOV: JMP MOVE ;MEMORY MOVE FOR LARGE MEMORY COPY ?TIM: JMP ?TIME ;GET THE TIME ?BNKSL: JMP SELMEM ;SELECT ALTERNATE BANK OF MEMORY ?STBNK: JMP SETBNK ;SELECT BANK FOR DMA OPERATION ?XMOV: JMP XMOVE ;SET BANK WHEN A BUFFER IS IN A BANK ; THAN 0 OR 1 DJDRV JMP DJSEL ;HOOK FOR SINGLE.COM PROGRAM ;RESERVED FOR SYSTEM IMPLEMENTOR JMP RESERV1 ;RESERVED FOR CP/M PLUS JMP RESERV2 ;RESERVED FOR CP/M PLUS ; ; DEVICE TABLE IS NOT IMPLEMENTED, SO RETURN HL=0 DEVTBL: LXI H,0 RET ; ; FLUSH ROUTINE IS NOT IMPLEMENTED, SO RETURN A=0 FLUSH: XRA A RET ; ; DRIVE TABLE IS NOT USED, SO RETURN HL=0FFFEH DRVTBL: LXI H,0FFFEH RET ; ; THE FOLLOWING JUMPS FROM THE BIOS JUMP VECTOR ; ARE NOT IMPLEMENTED: IF LDRBIOS AUXIST: AUXOUT: AUXIN: AUXOST: LIST: LISTST ENDIF ;LDRBIOS DEVINI: MULTIO: XMOVE: SELMEM: SETBNK: RESERV1: RESERV2: ?TIME: RET ************************************************************* * * * COLD-BOOT SIGN-ON MESSAGE * * * ************************************************************* PROMPT: IF LDRBIOS DB ACR,ALF,ALF DB 'LOADER FOR MORROW DESIGNS DJ2D CONTROLLER.' DB ACR,ALF,0 ENDIF ;LDRBIOS ; IF NOT LDRBIOS DB ACR,ALF,ALF DB 'CP/M 3.0 (V' ;CP/M VERSION NUMBER DB CPMREV/10+'0' DB '.' DB (CPMREV MOD 10)+'0' DB '), BIOS REV ' DB REVNUM/10+'0','.' ;REVISION NUMBER DB REVNUM MOD 10+'0' DB ACR,ALF DB 'FOR MORROW DESIGNS DJ2D CONTROLLER ' DB '@ 0' IF ORIGIN/4096 > 10 ;CONTROLER ORIGIN (HEX) DB ORIGIN/4096+'A'-10 ELSE DB ORIGIN/4096+'0' ENDIF ;ORIGIN/4096 IF (ORIGIN/256 AND 0FH) > 10 DB (ORIGIN/256 AND 0FH)+'A'-10 ELSE DB (ORIGIN/256 AND 0FH)+'0' ENDIF ;ORIGIN/256 DB '00H.' DB ACR,ALF,0 ENDIF ;NOT LDRBIOS ************************************************************* * * * UTILITY ROUTINE TO OUTPUT THE MESSAGE POINTED AT BY H&L, * * TERMINATED WITH A NULL. ONLY USED DURING COLD BOOT * * * ************************************************************* MESSAGE MOV A,M ;GET A CHARACTER OF THE ; MESSAGE INX H ;BUMP TEXT POINTER ANA A ;TEST FOR END RZ ;RETURN IF DONE PUSH H ;SAVE POINTER TO TEXT MOV C,A ;OUTPUT CHARACTER IN C CALL COUT ;OUTPUT THE CHARACTER POP H ;RESTORE THE POINTER JMP MESSAGE ;CONTINUE UNTIL NULL REACHED ************************************************************* * * * SYSTEM INITIALIZATION SUBROUTINE * * PUT ANY INITIALIZATION PROCEDURES REQUIRED BY YOUR SYSTEM * * HERE (E.G. SETTING UP UARTS, ETC.) * * * ************************************************************* IF LDRBIOS ;PERFORM ANY INITIALIZATIONS TINIT: MVI C,CLEAR ; THAT YOUR SYSTEM REQUIRES CALL COUT ;CLEAR THE CONSOLE SCREEN RET ENDIF ;LDRBIOS ************************************************************* * * * COLD BOOT ROUTINES * * * ************************************************************* CBOOT: IF LDRBIOS ;ITIALIZE TERMINAL OR WHATEVER CALL TINIT ENDIF ;LDRBIOS ; IF NOT LDRBIOS LXI SP,TPA ;SET UP STACK ENDIF ;NOT LDRBIOS ; LXI H,PROMPT ;PREP FOR SENDING SIGNON MESSAGE CALL MESSAGE ;SEND THE PROMPT XRA A ;SELECT DISK A STA CPMDRV STA CDISK ; IF NOT LDRBIOS CALL ?INIT ;INITIALIZE PAGE ZERO AND SCB JMP WBOOT ;WARM-BOOT ; ; SYSTEM INITIALIZATION SUBROUTINE ?INIT: MVI A,JMP ;SET JMPS AT ADDRESSES 0 AND 5 STA 0 STA 5 LXI H,WBOOTE SHLD 1 LHLD @MXTPA SHLD 6 LXI H,1 ;INIT SYSTEM CONTROL BLOCK SHLD @CIVEC SHLD @COVEC LXI H,2 SHLD @LOVEC LXI H,4 SHLD @AIVEC SHLD @AOVEC LXI H,LOG$MSG ; SIGN-ON MESSAGE ON CONSOLE CALL MESSAGE RET ************************************************************* * * * SUBROUTINE TO LOAD THE CCP INTO MEMORY AT ADDRESS 100H * * * ************************************************************* ?LDCCP: XRA A STA CCP$FCB+15 ;START WITH EXTENT 0 LXI H,0 SHLD FCB$NR ;RECORD 0 LXI D,CCP$FCB CALL OPEN ;OPEN FILE CCP.COM INR A JZ NO$CCP ;TELL IF NO FILE FOUND LXI D,0100H ;ELSE CALL SETBUF ;SET TO LOAD INTO TPA LXI D,128 CALL SETMULTI ;ALLOW UP TO 16K BYTES LXI D,CCP$FCB CALL REBOOT ;READ FILE INTO MEMORY RET ; ; PRINT ERROR MESSAGE IF CAN'T FIND CCP.COM ON DEFAULT DRIVE NO$CCP: LXI H,CCP$MSG CALL MESSAGE ;REPORT THIS CALL ?CONIN ;GET A RESPONSE JMP ?LDCCP ;AND TRY AGAIN ; ; CP/M BDOS FUNCTION INTERFACE USED TO LOAD CCP.COM OPEN: MVI C,15 JMP BDOSGO ;OPEN FILE CONTROL SETMULTI: MVI C,44 JMP BDOSGO ;SET MULTI RECORD COUNT REBOOT: MVI C,20 JMP BDOSGO ;READ RECORDS SETBUF: MVI C,26 JMP BDOSGO ;SETDMA BDOSGO: LHLD @MXTPA PCHL ; ; MISCELLANEOUS MESSAGES FOR CONSOLE LOG$MSG: DB 13,10,13,10,'CP/M VERSION 3.0',13,10,00 CCP$MSG: DB 13,10,'BIOS ERR ON A: NO CCP.COM FILE',00 ; ; FILE CONTROL BLOCK USED TO LOAD CCP.COM CCP$FCB: DB 1,'CCP ','COM',0,0,0,0 DS 16 FCB$NR: DB 0,0,0 ENDIF ;NOT LDRBIOS ************************************************************* * * * WARM-BOOT SUBROUTINE * * * ************************************************************* WBOOT: IF NOT LDRBIOS LXI SP,TPA ;SET UP STACK POINTER ENDIF ;NOT LDRBIOS ; LXI D,BUFF ;SET UP INITIAL DMA ADDRESS CALL SETDMA ; IF NOT LDRBIOS CALL ?LDCCP ;LOAD THE CCP.COM IN THE TPA ENDIF ;NOT LDRBIOS ; MVI A,JMP ;SET UP JUMPS AT 0,5 STA 0 STA 5 LXI H,WBOOTE SHLD 1 ; IF NOT LDRBIOS LHLD @MXTPA SHLD 6 ************************************************************* * * * THIS CONDITIONAL IS USED IF YOU WANT THE SYSTEM TO READ * * THE USER/DRIVE BYTE AT ADDRESS 4 DURING EACH WARM-BOOT, * * TO MAINTAIN COMPATABILITY WITH CERTAIN CP/M 2.2 PROGRAMS * * THAT MODIFY THIS BYTE TO CHANGE DEFAULT USER AREAS OF THE * * DRIVE. MAKING THIS CONDITIONAL TRUE MAY CAUSE SOME * * UNUSUAL SIDE-EFFECTS WHEN YOU WARM-BOOT WHILE LOGGED INTO * * ANY DRIVE OTHER THAN 'A' DRIVE. NOTE ALSO THAT THE * * LOCATION OF THE WARM-BOOT USER AND DRIVE BYTES IN THE SCB * * IS UNDOCUMENTED, SO IT MAY BE CHANGED SINCE THE BETA 1.2 * * VERSION THAT WE EVALUATED, SO USE IT WITH A GREAT DEAL * * OF CAUTION. * * * ************************************************************* IF UD2 ;COPY USER/DRIVE BYTE FROM ADDRESS 4 INTO THE SCB LHLD 1 ;GET ADDRESS PAGE OF BIOS DCR H ;POINT TO DEFAULT DRIVE BYTE IN SCB MVI L,0AFH ; LDA 4 ;GET DEFAULT DRIVE FROM ; USER/DRIVE BYTE ANI 0FH ; MOV M,A ;STORE DRIVE IN SCB INX H ;POINT TO DEFAULT USER BYTE IN SCB LDA 4 ;GET DEFAULT USER FROM U/D BYTE RRC RRC RRC RRC ANI 0FH MOV M,A ;STORE USER IN SCB ; ENDIF ;UD2 ENDIF ;NOT LDRBIOS ; LDA CDISK ;PUT CURRENT DISK INTO A MOV C,A ; IF NOT LDRBIOS JMP 0100H ;JMP TO CCP ENDIF ;NOPT LDRBIOS ; IF LDRBIOS RET ;RETURN TO LOADER ENDIF ;LDRBIOS ************************************************************* * * * GENERAL PURPOSE MEMORY MOVE SUBROUTINE. * * MOVES BC BYTES FROM DE TO HL * * * ************************************************************* MOVE: LDAX D MOV M,A INX D INX H DCR C JNZ MOVE MOV A,B ORA C RZ DCR B JMP MOVE ************************************************************* * * * SETSEC JUST SAVES THE DESIRED SECTOR TO SEEK TO UNTIL AN * * ACTUAL READ OR WRITE IS ATTEMPTED. * * * ************************************************************* SETSEC MOV A,C ;SAVE THE SECTOR NUMBER STA CPMSEC ;CP/M SECTOR # RET ************************************************************* * * * SETDMA SAVES THE DMA ADDRESS FOR THE DATA TRANSFER. * * * ************************************************************* SETDMA MOV H,B ;HL <- BC MOV L,C SHLD CPMDMA ;CP/M DMA ADDRESS RET ************************************************************* * * * HOME IS TRANSLATED INTO A SEEK TO TRACK ZERO. * * * ************************************************************* HOME MVI C,0 ;TRACK TO SEEK TO ************************************************************* * * * SETTRK SAVES THE TRACK # TO SEEK TO. NOTHING IS DONE AT * * THIS POINT, EVERYTHING IS DEFFERED UNTIL A READ OR WRITE. * * * ************************************************************* SETTRK MOV A,C ;A <- TRACK # STA CPMTRK ;CP/M TRACK # RET ************************************************************* * * * SECTRAN TRANSLATES A LOGICAL SECTOR # INTO A PHYSICAL * * SECTOR #. * * * ************************************************************* SECTRAN INX B PUSH D ;SAVE TABLE ADDRESS PUSH B ;SAVE SECTOR # CALL GETDPB ;GET DPB ADDRESS INTO HL MOV A,M ;GET # OF CP/M SECTORS/TRACK ORA A ;CLEAR CARY RAR ;DIVIDE BY TWO SUB C PUSH PSW ;SAVE ADJUSTED SECTOR JM SIDETWO SIDEA POP PSW ;DISCARD ADJUSTED SECTOR POP B ;RESTORE SECTOR REQUESTED POP D ;RESTOR ADDRESS OF XLT TABLE SIDEONE XCHG ;HL <- &(TRANSLATION TABLE) DAD B ;BC = OFFSET INTO TABLE MOV L,M ;HL <- PHYSICAL SECTOR MVI H,0 RET SIDETWO LXI B,17 ;OFFSET TO SIDE BIT DAD B MOV A,M ANI 8 ;TEST FOR DOUBLE SIDED JZ SIDEA ;MEDIA IS ONLY SINGLE SIDED POP PSW ;RETRIEVE ADJUSTED SECTOR POP B CMA ;MAKE SECTOR REQUEST POSITIVE INR A MOV C,A ;MAKE NEW SECTOR THE REQUESTED ; SECTOR POP D CALL SIDEONE MVI A,80H ;SIDE TWO BIT ORA L ; AND SECTOR MOV L,A RET ************************************************************* * * * SETDRV SELECTS THE NEXT DRIVE TO BE USED IN READ/WRITE * * OPERATIONS. IF THE DRIVE HAS NEVER BEEN SELECTED BEFORE, * * A PARAMETER TABLE IS CREATED WHICH CORRECTLY DESCRIBES * * THE DISKETTE CURRENTLY IN THE DRIVE. DISKETTES CAN BE OF * * FOUR DIFFERENT SECTOR SIZES: * * 1) 128 BYTES SINGLE DENSITY. * * 2) 256 BYTES DOUBLE DENSITY. * * 3) 512 BYTES DOUBLE DENSITY. * * 4) 1024 BYTES DOUBLE DENSITY. * * * ************************************************************* SETDRV MOV A,C ;SAVE THE DRIVE # STA CPMDRV CPI MAXDISK ;CHECK FOR A VALID DRIVE # JNC ZRET ;ILLEGAL DRIVE # MOV A,E ;TEST IF DRIVE EVER LOGGED ; IN BEFORE ANI 1 JNZ SETDRV1 ;BIT 0 OF E = 0 -> NEVER ; SELECTED BEFORE MVI A,1 ;SELECT SECTOR 1 OF TRACK 1 STA TRUESEC STA CPMTRK CALL FILL ;FLUSH BUFFER AND REFILL JC ZRET ;TEST FOR ERROR RETURN CALL DJSTAT ;GET STATUS ON CURRENT DRIVE ANI 2CH ;LOK AT SIDE AND DENSITY BITS MOV E,A ANI 20H MOV A,E JNZ SETDR1 ORI 10H SETDR1: RAR PUSH PSW ;SAVE DJSTAT 1/2 SIDED INFO ANI 6 LXI H,XLTS ;TABLE OF XLT ADDRESSES PUSH H MOV E,A MVI D,0 DAD D PUSH H ;SAVE POINTER TO PROPER XLT CALL GETDPB ;GET DPH POINTER INTO DE XCHG ; POP D MVI B,2 ;NUMBER OF BYTES TO MOVE CALL MOVLOP ;MOVE THE ADDRESS OF XLT LXI D,10 ;OFFSET TO DPB POINTER DAD D ;HL <- &DPH.DPB XCHG POP H POP PSW ;OFFSET TO CORRECT DPB MOV C,A MVI B,0 DAD B ;ADD TO TRANSLATE TABLE ; TO POINT TO DENSITY ; (THE DPB TABLE IS CLEVERLY ; LOCATED RIGHT AFTER THE ; XLT TABLE) XCHG ;PUT DPB ADDRESS IN DPH MVI B,2 ;MOVE DPB ADDRESS INTO DPH CALL MOVLOP SETDRV1 CALL GETDPB ;GET ADDRESS OF DPB IN HL LXI B,17 ;OFFSET TO SECTOR SIZE DAD B MOV A,M ;GET SECTOR SIZE ANI 7H STA SECSIZ MOV A,M RAR RAR RAR RAR ANI 0FH STA SECPSEC XCHG ;HL <- DPH RET ZRET LXI H,0 ;SELDRV ERROR EXIT RET ************************************************************* * * * GETDPB RETURNS HL POINTING TO THE DPB OF THE CURRENTLY * * SELECTED DRIVE, DE POINTING TO DPH. * * * ************************************************************* GETDPB LDA CPMDRV ;GET DRIVE # LXI H,DPZERO LXI D,19H GETDP1: ORA A JZ GETDP2 DAD D DCR A JMP GETDP1 ; GETDP2: PUSH H ;SAVE ADDRESS OF DPH LXI D,12 ;OFFSET TO DPB DAD D MOV A,M ;GET LOW BYTE OF DPB ADDRESS INX H MOV H,M ;GET LOW BYTE OF DPB MOV L,A POP D RET ************************************************************* * * * XLTS IS A TABLE OF ADDRESS THAT POINT TO EACH OF THE XLT * * TABLES FOR EACH SECTOR SIZE. * * * ************************************************************* XLTS DW XLT128 ;XLT FOR 128 BYTE SECTORS DW XLT256 ;XLT FOR 256 BYTE SECTORS DW XLT512 ;XLT FOR 512 BYTE SECTORS DW XLT124 ;XLT FOR 1024 BYTE SECTORS ************************************************************* * * * THE TABLE FOLLOWING THE XLT'S IS A TABLE OF THE DPB'S, * * USED BY THE SETDRV SUBROUTINE TO CALCULATE DENSITY * * * ************************************************************* DW DPB128S ; 128 BYTE SECTORS SINGLE SIDE DW DPB256S ; 256 BYTE SECTORS SINGLE SIDE DW DPB512S ; 512 BYTE SECTORS SINGLE SIDE DW DP1024S ; 1024 BYTE SECTORS SINGLE SIDE DW DPB128D ; 128 BYTE SECTORS DOUBLE SIDE DW DPB256D ; 256 BYTE SECTORS DOUBLE SIDE DW DPB512D ; 512 BYTE SECTORS DOUBLE SIDE DW DP1024D ; 1024 BYTE SECTORS DOUBLE SIDE ************************************************************* * * * WRITE ROUTINE MOVES DATA FROM MEMORY INTO THE BUFFER. IF * * THE DESIRED CP/M SECTOR IS NOT CONTAINED IN THE DISK * * BUFFER, THE BUFFER IS FIRST FLUSHED TO THE DISK IF IT HAS * * EVER BEEN WRITTEN INTO, THEN A READ IS PERFORMED INTO THE * * BUFFER TO GET THE DESIRED SECTOR. ONCE THE CORRECT SECTOR * * IS IN MEMORY, THE BUFFER WRITTEN INDICATOR IS SET, SO THE * * BUFFER WILL BE FLUSHED, THEN THE DATA IS TRANSFERRED INTO * * THE BUFFER. * * * ************************************************************* WRITE MOV A,C ;SAVE WRITE COMMAND TYPE STA WRITTYP MVI A,1 ;SET WRITE COMMAND DB (MVI) OR (B*8) ;THIS "MVI B" INSTRUCTION ; CAUSES THE FOLLOWING ; "XRA A" TO BE SKIPPED OVER. ************************************************************* * * * READ ROUTINE TO BUFFER DATA FROM THE DISK. IF THE SECTOR * * REQUESTED FROM CP/M IS IN THE BUFFER, THEN THE DATA IS * * SIMPLY TRANSFERRED FROM THE BUFFER TO THE DESIRED DMA * * ADDRESS. IF THE BUFFER DOES NOT CONTAIN THE DESIRED * * SECTOR, THE BUFFER IS FLUSHED TO THE DISK IF IT HAS EVER * * BEEN WRITTEN INTO, THEN FILLED WITH THE SECTOR FROM THE * * DISK THAT CONTAINS THE DESIRED CP/M SECTOR. * * * ************************************************************* READ XRA A ;SET THE COMMAND TYPE TO READ STA RDWR ;SAVE COMMAND TYPE ************************************************************* * * * REDWRT CALCULATES THE PHYSICAL SECTOR ON THE DISK THAT * * CONTAINS THE DESIRED CP/M SECTOR, THEN CHECKS IF IT IS * * THE SECTOR CURRENTLY IN THE BUFFER. IF NO MATCH IS MADE, * * THE BUFFER IS FLUSHED IF NECESSARY AND THE CORRECT SECTOR * * READ FROM THE DISK. * * * ************************************************************* REDWRT MVI B,0 ;THE 0 IS MODIFIED TO CONTAIN SECSIZ EQU $-1 ; THE LOG2 OF THE PHYSICAL ; SECTOR SIZE/128 ON THE ; CURRENTLY SELECTED DISK. LDA CPMSEC ;GET THE DESIRED CP/M SECTOR # PUSH PSW ;TEMPORARY SAVE ANI 80H ;SAVE ONLY THE SIDE BIT MOV C,A ;REMEMBER THE SIDE POP PSW ;GET THE SECTOR BACK ANI 7FH ;FORGET THE SIDE BIT DCR A ;TEMPORARY ADJUSTMENT DIVLOOP DCR B ;UPDATE REPEAT COUNT JZ DIVDONE ORA A ;CLEAR THE CARRY FLAG RAR ;DIVIDE THE CP/M SECTOR # BY ; THE SIZE OF THE PHYSICAL ; SECTORS JMP DIVLOOP ; DIVDONE INR A ORA C ;RESTORE THE SIDE BIT STA TRUESEC ;SAVE THE PHYSICAL SECTOR ; NUMBER LXI H,CPMDRV ;POINTER TO DESIRED DRIVE, ; AND SECTOR LXI D,BUFDRV ;POINTER TO BUFFER DRIVE, ; TRACK AND SECTOR MVI B,4 ;COUNT LOOP DTSLOP DCR B ;TEST IF DONE WITH COMPARE JZ SECMOV ;YES, MATCH. GO MOVE THE DATA LDAX D ;GET A BYTE TO COMPARE CMP M ;TEST FOR MATCH INX H ;BUMP POINTERS TO NEXT DATA ; ITEM INX D JZ DTSLOP ;MATCH, CONTINUE TESTING ************************************************************* * * * IF DRIVE, TRACK, AND SECTOR DON'T MATCH, THEN FLUSH THE * * BUFFER IF NECESSARY AND THEN REFILL. * * * ************************************************************* CALL FILL ;FILL THE BUFFER WITH CORRECT ; PHYSICAL SECTOR RC ;NO GOOD, RETURN WITH ERROR ; INDICATION ************************************************************* * * * SECMOV HAS BEEN MODIFIED TO CAUSE EITHER A TRANSFER INTO * * OR OUT OF THE BUFFER. * * * ************************************************************* SECMOV LDA CPMSEC ;GET THE CP/M SECTOR TO ; TRANSFER DCR A ;ADJUST TO PROPER SECTOR IN ; BUFFER ANI 0 ;STRIP OFF HIGH ORDERED BITS SECPSEC EQU $-1 ;THE 0 IS MODIFIED TO ; REPRESENT THE # OF ; CP/M SECTORS PER PHYSICAL ; SECTOR MOV L,A ;PUT INTO HL MVI H,0 DAD H ;FORM OFFSET INTO BUFFER DAD H DAD H DAD H DAD H DAD H DAD H LXI D,BUFFER ;BEGINNING ADDRESS OF BUFFER DAD D ;FORM BEGINNING ADDRESS OF ; SECTOR TO TRANSFER XCHG ;DE = ADDRESS IN BUFFER LXI H,0 ;GET DMA ADDRESS, THE 0 IS ; MODIFIED TO ; CONTAIN THE DMA ADDRESS CPMDMA EQU $-2 MVI A,0 ;THE ZERO GETS MODIFIED TO ; CONTAIN A ZERO IF A READ, ; OR A 1 IF WRITE RDWR EQU $-1 ANA A ;TEST WHICH KIND OF OPERATION JNZ INTO ;TRANSFER DATA INTO THE BUFFER OUTOF CALL MOVER XRA A RET INTO XCHG ; CALL MOVER ;MOVE THE DATA, HL = DESTINATION ; DE = SOURCE MVI A,1 STA BUFWRTN ;SET BUFFER WRITTEN INTO FLAG MVI A,0 ;CHECK FOR DIRECTORY WRITE WRITTYP EQU $-1 DCR A MVI A,0 STA WRITTYP ;SET NO DIRECTORY WRITE RNZ ;NO ERROR EXIT ************************************************************* * * * FLUSHA WRITES THE CONTENTS OF THE BUFFER OUT TO THE DISK * * IF IT HAS EVER BEEN WRITTEN INTO. * * * ************************************************************* FLUSHA MVI A,0 ;THE 0 IS MODIFIED TO REFLECT ; IF THE BUFFER HAS BEEN ; WRITTEN INTO BUFWRTN EQU $-1 ANA A ;TEST IF WRITTEN INTO RZ ;NOT WRITTEN, ALL DONE LXI H,DJWRITE ;WRITE OPERATION ************************************************************* * * * PREP PREPARES TO READ/WRITE THE DISK. RETRIES ARE * * ATTEMPTED.UPON ENTRY, H&L MUST CONTAIN THE READ OR WRITE * * OPERATION ADDRESS. * * * ************************************************************* PREP XRA A ;RESET BUFFER WRITTEN FLAG STA BUFWRTN SHLD RETRYOP ;SET UP THE READ/WRITE ; OPERATION MVI B,RETRIES ;MAXIMUM NUMBER OF RETRIES ; TO ATTEMPT RETRYLP PUSH B ;SAVE THE RETRY COUNT LDA BUFDRV ;GET DRIVE NUMBER INVOLVED ; IN THE OPERATION MOV C,A CALL DJDRV ;SELECT THE DRIVE LDA BUFTRK ANA A ;TEST FOR TRACK ZERO MOV C,A PUSH B CZ DJHOME ;HOME THE DRIVE IF TRACK 0 POP B ;RESTORE TRACK # CALL DJTRK ;SEEK TO PROPER TRACK LDA BUFSEC ;GET SECTOR INVOLVED ; IN OPERATION PUSH PSW ;SAVE THE SECTOR # RLC ;BIT 0 OF A EQUALS SIDE # ANI 1 ;STRIP OFF UNNECESSARY BITS MOV C,A ;C <- SIDE # CALL DJSIDE ;SELECT THE SIDE POP PSW ;A <- SECTOR # ANI 7FH ;STRIP OFF SIDE BIT MOV C,A ;C <- SECTOR # CALL DJSEC ;SET THE SECTOR TO TRANSFER LXI B,BUFFER ;SET THE DMA ADDRESS CALL DJDMA CALL DJREAD ;THE READ OPERATION IS ; MODIFIED TO WRITE RETRYOP EQU $-2 POP B ;RESTORE THE RETRY COUNTER MVI A,0 ;NO ERROR EXIT STATUS RNC ;RETURN NO ERROR DCR B ;UPDATE THE RETRY COUNTER STC ;ASSUME RETRY COUNT EXPIRED MVI A,0FFH ;ERROR RETURN RZ JMP RETRYLP ;TRY AGAIN ************************************************************* * * * FILL FILLS THE BUFFER WITH A NEW SECTOR FROM THE DISK. * * * ************************************************************* FILL CALL FLUSHA ;FLUSH BUFFER FIRST RC ;CHECK FOR ERROR LXI D,CPMDRV ;UPDATE THE DRIVE, TRACK, ; AND SECTOR LXI H,BUFDRV MVI B,3 ;NUMBER OF BYTES TO MOVE CALL MOVLOP ;COPY THE DATA LXI H,DJREAD JMP PREP ;SELECT DRIVE, TRACK, AND ; SECTOR. THEN READ THE ************************************************************* * * * MOVER MOVES 128 BYTES OF DATA. SOURCE POINTER IN DE, DEST * * POINTER IN HL. * * * ************************************************************* MOVER MVI B,128 ;LENGTH OF TRANSFER MOVLOP LDAX D ;GET A BYTE OF SOURCE MOV M,A ;MOVE IT INX D ;BUMP POINTERS INX H DCR B ;UPDATE COUNTER JNZ MOVLOP ;CONTINUE MOVING UNTIL DONE RET ************************************************************* * * * TERMINAL DRIVER SUBROUTINES. IOBYTE IS NOT USED. * * NOTE THAT THE CONSOLE DEVICE IS NOT THE DJ2D MEMORY * * MAPPED SERIAL I/O PORT. THE NORTHSTAR SERIAL PORT IS * * USED INSTEAD. * * * ************************************************************* ;I/O ROUTINES FOR NORTHSTAR MOTHERBOARD ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE I/O * * * ************************************************************* ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE INPUT * * * ************************************************************* CONIN: ;READ A CHARACTER IN 03H ANI 02H JZ CONIN ;WAIT TILL A CHARACTER IS ; READY IN 02H ;GET THE CHARACTER ANI 7FH ;STRIP PARITY RET ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE OUTPUT * * * ************************************************************* CONOUT: ;WRITE A CHARACTER IN 03H ANI 01H JZ CONOUT ;WAIT TILL THE BUFFER IS ; EMPTY MOV A,C ;WRITE THE CHARACTER OUT 02H RET ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE INPUT STATUS * * * ************************************************************* CONST: ;RETURN INPUT BUFFER STATUS IN 03H ANI 02H RZ ;RETURN NOT READY MVI A,0FFH RET ;THERE IS A CHARACTER READY ************************************************************* * * * LEFT SERIAL PORT ROUTINES. CONSOLE OUT STATUS * * * ************************************************************* CONOST: ;RETURN OUTPUT BUFFER STATUS IN 03H ANI 01H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY IF NOT LDRBIOS ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT INPUT * * * ************************************************************* AUXIN: ;READ A CHARACTER IN 05H ANI 02H JZ RTIN ;WAIT TILL A CHARACTER IS ; READY IN 04H ;GET THE CHARACTER ANI 7FH ;STRIP PARITY RET ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT OUTPUT * * * ************************************************************* AUXOUT: ;WRITE A CHARACTER IN 05H ANI 01H JZ RTOUT ;WAIT TILL THE BUFFER IS ; EMPTY MOV A,C ;WRITE THE CHARACTER OUT 04H RET ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT INPUT STATUS * * * ************************************************************* AUXIST: ;RETURN INPUT BUFFER STATUS IN 05H ANI 02H RZ ;RETURN NOT READY MVI A,0FFH RET ;THERE IS A CHARACTER READY ************************************************************* * * * RIGHT SERIAL PORT ROUTINES. RIGHT OUT STATUS * * * ************************************************************* AUXOST: ;RETURN OUTPUT BUFFER STATUS IN 05H ANI 01H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY ************************************************************* * * * PARALLEL PORT ROUTINES. PARALLEL INPUT * * * ************************************************************* PARIN: ;READ A CHARACTER IN 06H ANI 01H JZ PARIN ;WAIT TILL A CHARACTER IS ; READY IN 00H ;GET THE CHARACTER PUSH PSW MVI A,30H ;RESET THE PARALLEL INPUT ; FLAG OUT 06H POP PSW ANI 7FH ;STRIP PARITY RET ************************************************************* * * * PARALLEL PORT ROUTINES. PRINTER OUTPUT * * * ************************************************************* LIST: ;WRITE A CHARACTER IN 06H ANI 02H JZ LIST ;WAIT TILL THE BUFFER IS ; EMPTY MVI A,20H ;RESET THE PARALLEL OUTPUT ; FLAG OUT 06H MOV A,C ;WRITE THE CHARACTER, STROBE ; BIT 7 NSPOUT: ORI 80H OUT 00H ANI 7FH OUT 00H ORI 80H OUT 00H RET ************************************************************* * * * PARALLEL PORT ROUTINES. INPUT STATUS * * * ************************************************************* PINPST: ;RETURN INPUT BUFFER STATUS IN 06H ANI 01H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY ************************************************************* * * * PARALLEL PORT ROUTINES. LIST DEVICE STATUS * * * ************************************************************* LISTST: ;RETURN OUTPUT BUFFER STATUS IN 06H ANI 02H RZ ;RETURN NOT READY MVI A,0FFH RET ;RETURN READY ENDIF ;NOT LDRBIOS ************************************************************* * * * XLT TABLES (SECTOR SKEW TABLES) FOR CP/M 2.0. THESE * * TABLES DEFINE THE SECTOR TRANSLATION THAT OCCURS WHEN * * MAPPING CP/M SECTORS TO PHYSICAL SECTORS ON THE DISK. * * THERE IS ONE SKEW TABLE FOR EACH OF THE POSSIBLE SECTOR * * SIZES. CURRENTLY THE TABLES ARE LOCATED ON TRACK 0 * * SECTORS 6 AND 8. THEY ARE LOADED INTO MEMORY IN THE CBIOS * * RAM BY THE COLD BOOT ROUTINE. * * * ************************************************************* XLT128 DB 0 DB 1,7,13,19,25 DB 5,11,17,23 DB 3,9,15,21 DB 2,8,14,20,26 DB 6,12,18,24 DB 4,10,16,22 XLT256 DB 0 DB 1,2,19,20,37,38 DB 3,4,21,22,39,40 DB 5,6,23,24,41,42 DB 7,8,25,26,43,44 DB 9,10,27,28,45,46 DB 11,12,29,30,47,48 DB 13,14,31,32,49,50 DB 15,16,33,34,51,52 DB 17,18,35,36 XLT512 DB 0 DB 1,2,3,4,17,18,19,20 DB 33,34,35,36,49,50,51,52 DB 5,6,7,8,21,22,23,24 DB 37,38,39,40,53,54,55,56 DB 9,10,11,12,25,26,27,28 DB 41,42,43,44,57,58,59,60 DB 13,14,15,16,29,30,31,32 DB 45,46,47,48 XLT124 DB 0 DB 1,2,3,4,5,6,7,8 DB 25,26,27,28,29,30,31,32 DB 49,50,51,52,53,54,55,56 DB 9,10,11,12,13,14,15,16 DB 33,34,35,36,37,38,39,40 DB 57,58,59,60,61,62,63,64 DB 17,18,19,20,21,22,23,24 DB 41,42,43,44,45,46,47,48 ************************************************************* * * * EACH OF THE FOLLOWING TABLES DESCRIBES A DISKETTE WITH * * THE SPECIFIED CHARACTERISTICS. THE TABLES ARE CURRENTLY * * STORED ON TRACK 0 SECTOR 13. THEY ARE READ INTO MEMORY BY * * THE GOCPM ROUTINE IN THE CBIOS FOR CP/M VER 2.2. * * * ************************************************************* ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE FOR 128 BYTE * * SECTORS, SINGLE DENSITY, AND SINGLE SIDED. * * * ************************************************************* DPB128S DW 26 ;SPT CP/M SECTORS/TRACK DB 3 ;BSH BLOCK SHIFT FACTOR DB 7 ;BLM BLOCK MASK DB 0 ;EXM EXTENT MASK DW 242 ;DSM DISK SPACE MAXIMUM DW 63 ;DRM DIRECTORY MAXIMUM DB 0C0H ;AL0 INITIAL ALLOTARION DB 0 ;AL1 VECTORS DW 16 ;CKS DIRECTORY CHECK SIZE DW 2 ;OFF TRACK OFFSET DB 00 ;PSH PHYSICAL REC SHIFT FACT DB 00 ;PHM PHYSICAL RECORD MASK ;NEXT BYTE USED BY THE BIOS DB 1H ;16*((#CPM SECTORS/PHYSICAL ;SECTOR) -1) + LOG2(#BYTES ;PER SECTOR/128) + 1 + 8 IF ;DOUBLE SIDED. ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE FOR 256 BYTE * * SECTORS, DOUBLE DENSITY, AND SINGLE SIDED. * * * ************************************************************* DPB256S DW 52 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 242 ;DSM DW 127 ;DRM DB 0C0H ;AL0 DB 0 ;AL1 DW 32 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 12H ;16*((#CPM SECTORS/PHYSICAL ;SECTOR) -1) + LOG2(#BYTES ;PER SECTOR/128) + 1 + 8 ;IF DOUBLE SIDED. ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 512 BYTE SECTORS, * * DOUBLE DENSITY, AND SINGLE SIDED. * * * ************************************************************* DPB512S DW 60 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 280 ;DSM DW 127 ;DRM DB 0C0H ;AL0 DB 0 ;AL1 DW 32 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 33H ;16*((#CPM SECTORS/PHYSICAL ;SECTOR) -1) + LOG2(#BYTES ;PER SECTOR/128) + 1 + 8 ;IF DOUBLE SIDED. ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 1024 BYTE SECTORS,* * DOUBLE DENSITY, AND SINGLE SIDED. * * * ************************************************************* DP1024S DW 64 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 299 ;DSM DW 127 ;DRM DB 0C0H ;AL0 DB 0 ;AL1 DW 32 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 74H ;16*((#CPM SECTORS/PHYSICAL ;SECTOR) -1) + LOG2(#BYTES ;PER SECTOR/128) + 1 + ;8 IF DOUBLE SIDED. ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE FOR 128 BYTE SECTORS,* * SINGLE DENSITY, AND DOUBLE SIDED. * * * ************************************************************* DPB128D DW 52 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 1 ;EXM DW 242 ;DSM DW 127 ;DRM DB 0C0H ;AL0 DB 0 ;AL1 DW 32 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 9H ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 256 BYTE SECTORS, * * DOUBLE DENSITY, AND DOUBLE SIDED. * * * ************************************************************* DPB256D DW 104 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 486 ;DSM DW 255 ;DRM DB 0F0H ;AL0 DB 0 ;AL1 DW 64 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 1AH ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 512 BYTE SECTORS, * * DOUBLE DENSITY, AND DOUBLE SIDED. * * * ************************************************************* DPB512D DW 120 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 561 ;DSM DW 255 ;DRM DB 0F0H ;AL0 DB 0 ;AL1 DW 64 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 3BH ************************************************************* * * * THE FOLLOWING DPB DEFINES A DISKETTE AS 1024 BYTE SECTORS,* * DOUBLE DENSITY, AND DOUBLE SIDED. * * * ************************************************************* DP1024D DW 128 ;CP/M SECTORS/TRACK DB 4 ;BSH DB 15 ;BLM DB 0 ;EXM DW 599 ;DSM DW 255 ;DRM DB 0F0H ;AL0 DB 0 ;AL1 DW 64 ;CKS DW 2 ;OFF DB 00 ;PSH DB 00 ;PHM ; DB 7CH ************************************************************* * * * CP/M DISK PARAMETER HEADERS, (FOR 4 DRIVES) * * * ************************************************************* DPZERO DW 0 ;ADDRESS OF TRANSLATION TABLE ; (FILLED IN BY SETDRV) DW 0,0,0,0 ;USED BY BDOS DB 0 DB 0 ;MF MEDIA FLAG DW 0 ;ADDRESS OF DPB (FILLED IN ; BY SETDRV) DW CSV0 ;DIRECTORY CHECK VECTOR DW ALV0 ;ALLOCATION VECTOR DW DIRBCB ;DIRECTORY BUFFER CONTROL ; BLOCK DW 0FFFFH ;DTABCB DATA BUFFER CONTROL ; BLOCK DW 0FFFFH ;HASH DIRECTORY HASHING TABLE DB 0 ;HBANK BANK # OF HASH TABLE DPONE DW 0 DW 0,0,0,0 DB 0 DB 0 DW 0 DW CSV1 DW ALV1 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 DPTWO DW 0 DW 0,0,0,0 DB 0 DB 0 DW 0 DW CSV2 DW ALV2 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 DPTHRE DW 0 DW 0,0,0,0 DB 0 DB 0 DW 0 DW CSV3 DW ALV3 DW DIRBCB DW 0FFFFH DW 0FFFFH DB 0 ************************************************************* * * * DIRECTORY BUFFER CONTROL BLOCK * * * ************************************************************* DIRBCB: DB 0FFH ;DRV DRIVE NUMBER DB 00,00,00 ;REC# RECORD POSITION IN ; BUFFER DB 00 ;WFLG BUFFER WRITTEN FLAG DB 00 ;00 BIOS SCRATCH FLAG DW 0000 ;TRACK BUFFER CONTENTS' ; PHYSICAL TRACK DW 0000 ;SECTOR BUFFER CONTENTS' ; PHYSICAL SECTOR DW DIRBUF ;BUFFAD BUFFER ADDRESS ************************************************************* * * * CBIOS RAM LOCATIONS THAT DON'T NEED INITIALIZATION. * * * ************************************************************* CPMSEC DB 0 ;CP/M SECTOR # CPMDRV DB 0 ;CP/M DRIVE # CPMTRK DB 0 ;CP/M TRACK # TRUESEC DB 0 ;DISK JOCKEY SECTOR THAT ; CONTAINS CP/M SECTOR BUFDRV DB 0 ;DRIVE THAT BUFFER BELONGS TO BUFTRK DB 0 ;TRACK THAT BUFFER BELONGS TO BUFSEC DB 0 ;SECTOR THAT BUFFER BELONGS TO BUFFER DS 1024 ;MAXIMUM SIZE BUFFER FOR 1K ; SECTOR ************************************************************* * * * ALLOCATION VECTORS (FOR 4 DRIVES) * * EACH VECTOR REQUIRES 2 BITS FOR EACH BLOCK ON THE DRIVE * * * ************************************************************* ALV0 DS 150 ;ALLOCATION VECTOR FOR DRV A ALV1 DS 150 ;ALLOCATION VECTOR FOR DRV B ALV2 DS 150 ;ALLOCATION VECTOR FOR DRV C ALV3 DS 150 ;ALLOCATION VECTOR FOR DRV D ************************************************************* * * * CHECKSUM VECTORS (FOR 4 DRIVES) * * EACH VECTOR REQUIRES 1 BIT FOR EVERY 4 DIRECTORY ENTRIES * * * ************************************************************* CSV0 DS 64 ;DIRECTORY CHECK VECTOR ; DRIVE A CSV1 DS 64 ;DIRECTORY CHECK VECTOR ; DRIVE B CSV2 DS 64 ;DIRECTORY CHECK VECTOR ; DRIVE C CSV3 DS 64 ;DIRECTORY CHECK VECTOR ; DRIVE D ************************************************************* * * * DIRECTORY BUFFER * * * ************************************************************* DIRBUF DS 128 ;DIRECTORY BUFFER ; END