;ROM - Data Technology Corporation CP/M 2.2 ROM. ; ; +-----------------------+ ; | | ; | R O M B O O T | ; | | ; +-----------------------+ ; ; ; ; Version number: 2.2D ; Version date: March 19, 1981 ; ; Update date: March 24, 1981 ; ; Boots from logical unit 020h (floppy) ; if it is ready. Passes logical unit number ; to the BOOT routine in the A register. ; ; Update date: June 15, 1981 ; Modified to wait three seconds for boot ; LUN from keyboard. ; ; The following code is supplied to customers who ; purchase a hard/floppy disk system from DTC. ; The following code is written onto track 0 sector 0 ; of the hard disk. This routine is read into memory ; at location 0 by the user's PROM. This routine then ; loads the rest of the system into memory. ; ; ; The format of the Hard Disk Boot sectors are as follows: ; ; Logical Routine ; Sector Name ; ; 0 Boot program ; ; 1 thru 8 CCP ; ; 9 thru 22 BDOS ; ; 23 thru 32 DTC CBIOS ; ; VERS: EQU 22 FWA: EQU 800H - 20H BTFWA: EQU 0100h ORG FWA JMP START-FWA START: LXI B,0800h LXI H,FWA+0800h START1: DCX H DCX B LDAX B MOV M,A MOV A,C ORA B JNZ START1-FWA JMP BOOT ; ; ORG FWA + 20H BOOT: IF I696 MVI A,1 OUT 0FDh ;disable rom CNIN: EQU 0 ;Console input port CONSTS: EQU 1 ;Console status port RBR: EQU 2 ;Input status mask ENDIF IF I796 MVI A,80h OUT 0EBh ;disable rom CNIN: EQU 0ECh ;Console input port CONSTS: EQU 0EDh ;Console status port RBR: EQU 2 ;Input status mask PIT: EQU 0DEh ;Programmable interval timer ; Initialize console MVI A,0B6h ;Set PIT for 9600 baud OUT PIT+1 MVI A,8 OUT PIT+0 MVI A,0 OUT PIT+0 MVI A,04Eh ;Setup serial port OUT CONSTS MVI A,037h OUT CONSTS IN CNIN ENDIF LXI SP,STACK ; LXI B,3000 ;wait 3 seconds CALL DELAY IN CONSTS ANI RBR JZ BOOTA ;if no character IN CNIN ;Get character pressed SUI '0' JM BOOTA CPI 4 JNC BOOTA RRC RRC RRC STA LUN BOOTA: LXI D,BTFWA LXI H,CIOPB CALL RDISK ORA A JNZ BOOTA MOV A,C ANI FERR JNZ BOOTA LDA LUN JMP BTFWA ; ; ; CIOPB: DB RDCMD LUN: DB 0 DW 0 ;Read logical sec 0 DB 2 ;2 sectors in case of floppy DB 0 ;Perform retries ; Delay a period of time ; Enter: BC no. of milliseconds to delay DELCNT: EQU 4*1000 ;4 Mhz DELAY: MVI A,DELCNT/26 DLAY1: INX B DCX B DCR A JNZ DLAY1 DCX B MOV A,B ORA C JNZ DELAY RET ; Disk I/O Routines ; ; IF I696 ; E X E C EXEC: MVI B,BUSY ;Wait for not busy. MVI C,BUSY and (not BUSY) CALL WAITM RNZ MVI A,SLCT ;Alert controller OUT DIO+1 EXEC1: MOV C,B ;Wait for controller busy CALL WAITM RNZ MVI A,DODTA ;Enable data in OUT DIO+1 EXEC2: IN DIO+2 ;Get status XRI 0FFh JM EXEC2 ;If not requesting next byte ANI CMND+DIROUT JNZ EXEC3 ;If CMND or DIROUT false MOV A,M INX H OUT DIO ;Send byte from command buffer JMP EXEC2 EXEC3: CMP A ;Z:=1 RET ; ; ; ; ; WDISK - Output from memory buffer. ; ENTRY: HL = COMMAND BUFFER ADDRESS ; DE = DATA BUFFER ADDRESS ; WDISK: CALL EXEC ;Output command RNZ ;Return if timeout WDISK1: IN DIO+2 ;Read status ORA A JP WDISK1 ;If request is present ANI CMND JNZ GCMPS ;If done with transfer LDAX D ;Get the data byte OUT DIO INX D ;Advance buffer address JMP WDISK1 ; ; ; ; ; RDISK - Input to memory buffer. ; ; Entry: HL = command buffer address ; DE = data buffer address RDISK: CALL EXEC RNZ ;Return if timeout RDISK1: IN DIO+2 ;Read status ORA A JP RDISK1 ;If request is present ANI CMND JNZ GCMPS IN DIO STAX D INX D JMP RDISK1 ; ; ; ; ; WAITF - Wait for function to complete. WAITF: MVI B,REQ+CMND ;Wait for both REQ and CMND MOV C,B CALL WAITM RNZ ; ; Get completion status. GCMPS: IN DIO ;Get completion status MOV C,A GCMP1: IN DIO+2 ORA A JP GCMP1 ;If REQ not set MOV B,A IN DIO ;Get message byte RET ENDIF ; ; ; ; IF I796 ; EXEC - Output the command ; ; Enter: HL is the command buffer address ; DE - data transfer address. EXEC: MOV A,E ;Output DMA address OUT DIO+2 MOV A,D OUT DIO+3 MOV A,L OUT DIO+4 MOV A,H OUT DIO+5 MVI A,0 OUT DIO+6 OUT DIO+7 OUT DIO CMP A ;Z:=1 RET ; Disk read/write ; ; Entry: same as EXEC ; RDISK: WDISK: CALL EXEC RNZ ;Return if timeout ; WAITF - Wait until transfer done ; ; Enter: none ; Exit: when transfer completed WAITF: MVI B,CMDDON ;Wait for CMDDON MOV C,B CALL WAITM RNZ ;Return if timeout ; ; GCMPS - Get completion status ; ; Enter: none ; Exit: Status in C GCMPS: IN DIO+1 MOV C,A RET ENDIF ; WAITM - Wait for controller with timeout ; ; Entry: B=Status mask ; C=Status value ; Exit: Z=1 if OK, else timeout with A=C=TERR ; WAITM: PUSH D ;Save D PUSH H LXI H,138 ;Two minute timeout LXI D,0 ;Max wait @4MHZ is 868 ms WAITML: IF I696 IN DIO+2 ENDIF IF I796 IN DIO ENDIF ANA B ;Mask wait bits CMP C ;Check value JZ WAITM1 DCX D ;Not ready. Decrement time MOV A,D ORA E JNZ WAITML DCX H MOV A,H ORA L JNZ WAITML MVI B,0 ;Timeout MVI A,TERR ORA A WAITM1: POP H POP D ;Restore D MOV C,A ;Return status in C RET ; ORG FWA + 200H STACK: END