; B o o t C P / M f r o m d i s k. ; ; The CBOOT entry point gets control from the cold start ; loader and is responsible for the basic system initial- ; ization. This includes outputting a sign-on message and ; initializing the following page zero locations: ; ; 0,1,2: Set to the warmstart jump vector. ; 3: Set to the initial IOBYTE value. ; 4: Default and logged on drive. ; 5,6,7: Set to a jump to BDOS. ; ; It also constructs the BIOS tables DPH, DSKOFF and DSKMSK ; for the current configuration. ; ; Register A contains the logical unit number of the boot ; drive on entry. The exit address is to the CCP routine. ; ; JMP STSINI ;STSCOPY initialization entry. ;Must be at CBOOT-3. ; CBOOT: STA BTLUN ;Set boot logical unit number STA CIOBFS+1 CBOOT0: ; LXI SP,DBUF CALL URINIT ;Initialize unit record I/O STS: ;Configure disk controller and BIOS. ; MVI C,16*NDSK-1 ;Clear DPH table LXI H,DPH XRA A MOV M,A LXI D,DPH+1 CALL MOVDTA ; LXI H,CONTBL ;HL=address of configuration table entry MVI B,CONTLN ;B=# entries in configuration table ; ; CON1: ;Major loop ; ; Assign drive type ; MVI A,0FFh ;Initialize 2nd byte of DTYPE entry. STA CONFS MOV A,M ;Set LUN into command buffer STA CIOADT+1 RLC ;Put LUN into message. RLC RLC ANI 7 ADI '0' STA ADTLUN LDA BTLUN ;Boot LUN? CMP M JNZ CN1 INX H ;Yes MOV A,M ;Set boot TFC STA CIOBFS+5 INX H ;Set CCP beginning sector MOV A,M STA BTSLA0 INX H ;Set # sectors in CCP MOV A,M STA BTNSEC PUSH H LXI D,-DSKMSK ;Select the boot drive LHLD CONMSK DAD D MOV A,L STA CDISK POP H JMP CN2 CN1: INX H ;Skip warm boot parameters INX H INX H CN2: INX H MOV A,M ;Set drive type into command buffer STA CIOADT+4 INX H CPI 0FFh ;Does controller have Class 6, op code 1 JZ CON2 PUSH B ;Yes. Save major loop count PUSH H ;Save table pointer LXI H,CIOADT ;Output command buffer CALL EXEC CZ WAITF ;Wait for function to complete MOV A,C ;Completion status POP H ;Restore table pointer POP B ;Restore major loop count ANI FERR JZ CON2 PUSH B ;Save major loop count PUSH H ;Save table pointer LXI H,ADTMES CALL CONCHK ;Print message & check for host POP H ;Restore table pointer CON2: MOV A,M ;Get LUNiTYPE STA CONTYPE ; and save it. INX H MOV A,M ;Get track format codes STA CONTFC INX H MOV E,M ;Get # allocation blocks INX H MOV D,M INX H XCHG ; and save it. SHLD ALLBKS XCHG MOV C,M ;Get minor loop count INX H MOV E,M ;Get number of sectors INX H MOV D,M INX H ; ; Find DPB for this type ; PUSH H ;Save table pointer PUSH B ;Save counts LXI H,FPYTYP ;Initialize floppy type pointer LDA CONTYPE MOV B,A ANI TYPEDRV ;Floppy? MOV A,B POP B ;Restore counts JZ CON4 ANI TYPEN48+TYPEN96 ;No. Mini? JNZ CON3 MVI A,2 ;No. Hard disk. JMP CON6 CON3: LXI H,MINTYP CON4: SHLD FPYTY ;Save pointer to TFC table LHLD ALLBKS ;Normalize allocation block ; specification to single-density, LDA CONTYPE ; single-sided. ANI TYPESEC RAR MOV D,A CNZ DBLSHR MVI D,1 LDA CONTFC ANI 10101010b ;Double-sided format codes CNZ DBLSHR SHLD ALLINC LXI D,0 ;DSKOFF increment is 0. CON5: ;Minor loop return for floppy LHLD CONFS ;H=TFC selection bits, L=current TFC MOV A,H ;This TFC selected? CON51: INR L RAR JNC CON51 MOV H,A ;Save selection bits SHLD CONFS PUSH D ;Get DPB type and model MVI H,0 XCHG LHLD FPYTY DAD D DAD D POP D MOV A,M STA CONTYPE ;Save DPB type INX H MOV A,M ;Get DPB model CON6: XCHG ;Save DSKOFF increment SHLD OFFINC LXI D,16 ;Find prototype DPB LXI H,CONPBT CON7: CMP M JZ CON8 DAD D JMP CON7 CON8: PUSH B ;Save loop counts LXI D,CURDPB ;Move prototype DPB to buffer MVI C,16 CALL MOVDTA LXI H,CURDPB ;Set type in DPB LDA CONTYPE CPI TYPEFPY+0 ;Standard distribution format? JZ CON11 ;If so, use DPB as is. MOV M,A LXI D,6 ;Offset to # allocation blocks DAD D XCHG LHLD ALLBKS ;Compute # allocation blocks for this TFC MVI C,0 MOV B,A ANI TYPEFPY+TYPEMIN JZ CON10 LHLD ALLINC MOV A,B ANI TYPESEC RAR MOV C,A MOV A,B ANI 1 JZ CON9 INR C CON9: DCR C JM CON10 DAD H JMP CON9 CON10: DCX H XCHG MOV M,E ;Set # allocation blocks INX H MOV M,D CON11: LXI H,DPB CON12: ;Do we already have this DPB? XCHG ;End of DPB table? LHLD CONPB MOV A,D CMP H JNZ CON13 MOV A,E CMP L JZ CON16 CON13: PUSH D ;Save entry pointer MVI C,16 ;Compare entry LXI H,CURDPB CON14: LDAX D CMP M JNZ CON15 INX D INX H DCR C JNZ CON14 JMP CON17 ;Have a match CON15: POP H ;Restore entry pointer LXI D,16 ;Index to next entry DAD D JMP CON12 CON16: PUSH H XCHG ;Put new entry in DPB table LXI H,CURDPB MVI C,16 CALL MOVDTA XCHG SHLD CONPB ;Set new end of DPB table CON17: POP H INX H SHLD CONDPB ;Save DPB address ; ; Compute allocation vector increment ; LHLD CURDPB+6 ;Get # allocation blocks LXI D,7 ;Round up DAD D MVI D,3 CALL DBLSHR SHLD ALVINC ; ; Initialize current DPH entry ; LDA CURDPB CPI TYPEFPY+0 LXI H,0 ;Set translate table address to zero JNZ CON18 ;Standard distribution format? LXI H,XLTS ;Yes. Do translation. CON18: SHLD CONXLT ;Save translate table address LXI H,0 ;Set check vector address in CONDPH LDA CONTYPE ANI TYPEFPY+TYPEMIN ;Floppy? JZ CON20 CON19: LHLD CSVALUE CON20: SHLD CONCSV LXI H,0 ;Initialize current offset value SHLD OFFVAL SHLD OFFVAL+1 POP B ;Restore counts ; ; ; CON21: ;Minor loop return for hard disk LHLD CONTY ;Set DTYPE entry LDA CURDPB MOV M,A INX H LDA CONFS MOV M,A INX H SHLD CONTY LHLD CONMSK ;Set DSKMSK entry LDA CIOADT+1 MOV M,A INX H SHLD CONMSK LHLD OFFVAL+1 ;Set DSKOFF entry XCHG LHLD CONOFF LDA OFFVAL MOV M,A INX H MOV M,D INX H MOV M,E INX H SHLD CONOFF LHLD OFFINC DAD D SHLD OFFVAL+1 JNC CON22 LXI H,OFFVAL INR M CON22: PUSH B ;Save loop counts LHLD CONDPH ;Move DPH entry XCHG LXI H,CURDPH MVI C,16 CALL MOVDTA XCHG SHLD CONDPH POP B ;Restore loop counts LDA CONTYPE ANI TYPEFPY+TYPEMIN ;Floppy? LHLD ALVINC XCHG JZ CON24 CON23: PUSH D ;Yes. Floppy. LHLD CURDPB+12 XCHG LHLD CSVALUE ;Increment CSV value SHLD CONCSV DAD D SHLD CSVALUE POP D CON24: LHLD CONALV ;Increment ALV value DAD D SHLD CONALV DCR C ;Decrement minor loop count JZ CON25 LDA CONTYPE ANI TYPEFPY+TYPEMIN ;Floppy? JNZ CON5 JMP CON21 ; ; CON25: POP H ;Restore table pointer DCR B ;Decrement major loop count JNZ CON1 LDA CIOBFS+5 ;Is boot drive a hard disk? CPI 0FFh JZ CBOOT1 LXI H,DTYPE+1 ;No. Find the boot drive. MOV B,A LDA CDISK MOV E,A MVI D,0 DAD D DAD D MOV A,B CON26: CMP M ;This TFC? JZ CON27 INX H ;No. INX H INR E JMP CON26 CON27: MOV A,E STA CDISK CBOOT1: LXI H,SIGNON CALL PRINT XRA A STA IOBYTE JMP GOCPM ;Initialize for CP/M DBLSHR: XRA A ;Clear carry MOV A,H RAR MOV H,A MOV A,L RAR MOV L,A DCR D JNZ DBLSHR RET ; ;Print error message and halt if host drive ; ; Entry: HL = address of error message ; Exit: Only if not host drive ; CONCHK: CALL PRINT LXI H,BTLUN ;Is error on host drive? LDA CIOADT+1 CMP M RNZ LXI H,ADTMS1 ;Yes. Thats all. CALL PRINT HLT ; ; STSCOPY initialization ; STSERR: ;Fatal error return LHLD STSTACK ;Restore stack pointer SPHL MVI A,0FFh ;Set error flag RET STSINI: LXI H,0 ;Save stack pointer DAD SP SHLD STSTACK PUSH PSW ;Save LUN MVI A,0C9h ;RET STA CBOOT0 ;Don't do URINIT STA CBOOT1 ;Return to STSINI STA PRINT ;No printouts XRA A ;NOP the HLT STA STSERR-1 POP PSW ;Restore LUN CALL CBOOT CALL STS XRA A ;Clear error flag RET STSTACK: DS 2 ;STSCOPY stack pointer CIOADT: DB ADCMD,0,0,0,0,0 ; ; # SECTORS PER WARM BOOT ; HCCPLN: EQU (CBIOS-CCP)/256 ;Hard disk FCCPLN: EQU 24+(CBIOS-CCP-24*128)/256 ;8" floppy MCCPLN: EQU 14+(CBIOS-CCP-14*128)/256 ;5.25" floppy ; ; ; Configuration Table ; CONTBL: IF LUN0 DB 0 SHL 5 DB B0 DB 1+NF0+N48M0+N96M0 DB NH0*HCCPLN+NF0*FCCPLN+(N48M0+N96M0)*MCCPLN DB LUN0DAT DB LUN0TYPE+TYPEN48*N48M0+TYPEN96*N96M0 DB LUN0TFC DW ((LUN0SEC/HSTSPT-2-N48M0-N96M0)*CPMSPT/HSTSIB) DB LUN0NLD DW LUN0SEC ENDIF IF LUN1 DB 1 SHL 5 DB B1 DB 1+NF1+N48M1+N96M1 DB NH1*HCCPLN+NF1*FCCPLN+(N48M1+N96M1)*MCCPLN DB LUN1DAT DB LUN1TYPE+TYPEN48*N48M1+TYPEN96*N96M1 DB LUN1TFC DW ((LUN1SEC/HSTSPT-2-N48M1-N96M1)*CPMSPT/HSTSIB) DB LUN1NLD DW LUN1SEC ENDIF IF LUN2 DB 2 SHL 5 DB B2 DB 1+NF2+N48M2+N96M2 DB NH2*HCCPLN+NF2*FCCPLN+(N48M2+N96M2)*MCCPLN DB LUN2DAT DB LUN2TYPE+TYPEN48*N48M2+TYPEN96*N96M2 DB LUN2TFC DW ((LUN2SEC/HSTSPT-2-N48M2-N96M2)*CPMSPT/HSTSIB) DB LUN2NLD DW LUN2SEC ENDIF IF LUN3 DB 3 SHL 5 DB B3 DB 1+NF3+N48M3+N96M3 DB NH3*HCCPLN+NF3*FCCPLN+(N48M3+N96M3)*MCCPLN DB LUN3DAT DB LUN3TYPE+TYPEN48*N48M3+TYPEN96*N96M3 DB LUN3TFC DW ((LUN3SEC/HSTSPT-2-N48M3-N96M3)*CPMSPT/HSTSIB) DB LUN3NLD DW LUN3SEC ENDIF CONTLN: EQU ($-CONTBL)/12 ADTMES: DB CR,LF,'Assign Drive Type error on logical unit ' ADTLUN: DB '0.',0 ADTMS1: DB CR,LF,'Cannot continue!',0 ; ; Variables ; CONTYPE: DS 1 ;Current LUN type CONFS: DS 1 ;Current track format code CONTFC: DS 1 ;Track format code selection ALLINC: DS 2 ;Normalized allocation blocks ALLBKS: DW 0 ;# allocation blocks - 1 CSVALUE: DW CSV ;Current check vector address OFFVAL: DB 0 ;Current offset value DW 0 OFFINC: DS 2 ;Current offset increment ALVINC: DS 2 ;Logical hard disk allocation ; vector increment ; ; Table Pointers ; CONDPH: DW DPH ;Address of current DPH entry CONPB: DW DPB ;Address of next DPB entry CONTY: DW DTYPE ;Address of current DTYPE entry CONMSK: DW DSKMSK ;Address of current DSKMSK entry CONOFF: DW DSKOFF ;Address of current DSKOFF entry FPYTY: DW FPYTYP ;Address of next floppy type ; ; Current DPH entry ; CURDPH: CONXLT: DS 2 ;Translate table address DW 0,0,0 ;Work area for CP/M DW DIRBUF ;Directory address CONDPB: DS 2 ;DPB address CONCSV: DW 0 ;Check vector address CONALV: DW ALV ;Allocation vector address ; Current DPB entry ; CURDPB: DS 16 ; ;8" Floppy Type Generation Table ;Format: ; DB DPB type or 0FFh ; DB DPB model # ; ;DPB type bit 0 is # sided, bits 1-2 is sector size (0,1,2,3) ; FPYTYP: DB TYPEFPY+0,0 ;Single density, single-sided, FM DB TYPEFPY+1,1 ;Single density, double-sided, FM DB 0FFh,0 ;Invalid DB 0FFh,0 ;Invalid DB 0FFh,0 ;Invalic DB 0FFh,0 ;Invalid DB TYPEFPY+2,1 ;Double density, single-sided, MFM DB TYPEFPY+3,1 ;Double density, double-sided, MFM ; ;5.25" Floppy TYPEMIN: EQU 10000b ;Mini floppy ; ; MINTYP: DB TYPEMIN+0,3 ;Single density, single-sided, 48 TPI DB TYPEMIN+1,3 ;Single density, double-sided, 48 TPI DB TYPEMIN+0,3 ;Single density, single-sided, 96 TPI DB TYPEMIN+1,3 ;Single density, double-sided, 96 TPI DB TYPEMIN+2,3 ;Double density, single-sided, 48 TPI DB TYPEMIN+3,3 ;Double density, double-sided, 48 TPI DB TYPEMIN+2,3 ;Double density, single-sided, 96 TPI DB TYPEMIN+3,3 ;Double density, double-sided, 96 TPI ; ;Prototype DPBs ; CONPBT: DB 0 DW 26 DB 3,7,0 DW ((77-2)*26/CPMSIB)-1 DW 63 DB 11000000b,00000000b DW 16,2 DB 1 ;256 bytes/sector, MFM DW CPMSPT DB 4,15,0 DW 0,127 DB 11000000b,00000000b DW 32,2 DB 2 ;logical hard disk DW CPMSPT DB 4,15,0 DW 0,511 DB 11111111b,00000000b DW 0,2 DB 3 ;5.25" floppy DW CPMSPT DB 4,15,0 DW 0,63 DB 10000000b,00000000b DW 16,3 CONPLN: EQU ($-CONPBT)/16 SIGNON: DB CR,LF,LF,'DTC '