; ; CP/M COLDSTART LOADER ; ; ; THIS PROGRAM IS LOADED AT LOCATION ZERO ; BY THE BOOTSTRAP PROGRAM, AND EXECUTED. ; ITS PURPOSE IS TO LOAD AND EXECUTE THE ; CP/M DISK OPERATING SYSTEM AT THE TOP ; OF THE MEMORY IN USE. ; FALSE SET 0 ;DEFINE VALUE OF FALSE. TRUE SET NOT FALSE ;DEFINE VALUE OF TRUE. ; ; MSIZE EQU 64 ;MEMORY SIZE IN DECIMAL KB. SPT SET 26 ;NUMBER OF SECTORS PER TRACK. DISK SET 0E8H ;DISK PORT BASE ADDRESS. ; ; DCOM SET DISK ;COMMAND PORT DSTAT SET DISK ;STATUS PORT TRACK SET DISK+1 ;TRACK PORT SECT SET DISK+2 ;SECTOR PORT DATA SET DISK+3 ;DATA PORT WAIT SET DISK+4 ;WAIT PORT DCONT SET DISK+4 ;CONTROL PORT ; CBASE EQU (MSIZE-20)*1024 CPMB EQU CBASE+3400H ;START OF CP/M BOOTE: EQU CPMB+1600H ;COLD BOOT ENTRY POINT NSECTS EQU 51 ;SECTORS OF CP/M RTCNT SET 10 ;NUMBER OF RETRYS BOOT: MVI E,RTCNT ;GET RETRY COUNT BLOOP: LXI SP,100H LXI H,CPMB ;CP/M STARTS HERE MVI D,NSECTS ;NO. OF SECTORS TO READ MVI C,2 ;SECTOR NO. RNTRK: MVI B,4 ;FOR HEAD LOAD MOV A,C ;SECTOR IN A RNSEC: CALL READ ;READ FIRST SECTOR DCR D ;IF DONE JZ BOOTE ;GO TO CP/M MVI B,0 ;FOR NO HEAD LOAD INR C ;INCREMENT TRACK COUNT MOV A,C ;DONE WITH CPI SPT+1 ;THIS TRACK? JC RNSEC ;IF NOT, READ NEXT SECTOR MVI A,52H ;STEP COMMAND OUT DCOM ;ISSUE COMMAND WAIT1: IN WAIT ORA A JM WAIT1 MVI C,1 ;SECTOR NO. JMP RNTRK ;READ NEXT TRACK. READ: OUT SECT ;SET SECTOR REG. CALL CHECK ;CHECK FOR ERROR MVI A,88H ;COMMAND FOR READ ORA B ;GET HEAD LOAD BIT OUT DCOM ;ISSUE COMMAND XTHL XTHL XTHL XTHL RLOOP: IN DSTAT ANI 2 JZ RLOOP IN DATA MOV M,A INX H RRLOOP: IN WAIT ORA A JM RLOOP CHECK: IN DSTAT ;READ STATUS ANI 9DH ;LOOK AT ERROR BITS RZ ;OK IF ZERO DCR E ;DECREMENT RETRY COUNT JNZ BLOOP ;TRY AGAIN IF NOT ZERO STA EC ;SAVE ERROR CODE HERE: JMP HERE ;LOOP ORG 7DH ;PUT JUMP HERE JMP BOOT ;JUMP INTO BOOT EC: END ;END OF BOOT