;
; TARBELL ELECTRONICS
; CP/M COLDSTART LOADER
; VERSION OF 3-22-'79.
;
; 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 EQU 0 ;DEFINE VALUE OF FALSE.
TRUE EQU NOT FALSE ;DEFINE VALUE OF TRUE.
;
;********* THIS IS THE AREA TO MAKE CHANGES IN ***********
;********* FOR DIFFERENT SYSTEM CONFIGURATIONS ***********
; **
MSIZE EQU 61 ;MEMORY SIZE IN DECIMAL KB. **
DELTA EQU FALSE ;TRUE IF DELTA PRODUCTS CPU **
PERSCI EQU FALSE ;TRUE FOR PERSCI DRIVES. **
DUBSID EQU FALSE ;TRUE FOR DOUBLE SIDED SYSTEMS. **
SPT EQU 26 ;NUMBER OF SECTORS PER TRACK. **
DISK EQU 0F8H ;DISK PORT BASE ADDRESS. **
; **
;*********************************************************
;*********************************************************
;
DCOM EQU DISK ;COMMAND PORT.
DSTAT EQU DISK ;STATUS PORT.
TRACK EQU DISK+1 ;TRACK PORT.
SECT EQU DISK+2 ;SECTOR PORT.
DATA EQU DISK+3 ;DATA PORT.
WAIT EQU DISK+4 ;WAIT PORT.
DCONT EQU DISK+4 ;CONTROL PORT.
CBASE EQU (MSIZE-20)*1024
CPMB EQU CBASE+3400H;START OF CP/M.
BDOS EQU CPMB+800H ;START OF BDOS.
BIOS EQU CPMB+1600H ;START OF BIOS.
BOOTE EQU CPMB+1600H ;COLD BOOT ENTRY POINT.
NSECTS EQU 51 ;SECTORS OF CP/M.
RTCNT EQU 10 ;NUMBER OF RETRYS.
ORG 0 ;START OF LOADER.
BOOT: MVI E,RTCNT ;GET RETRY COUNT.
IF DELTA ;IF USING DELTA PRODUCTS CPU.
MVI A,1 ;CODE TO KICK OUT ROM
OUT 9
ENDIF
BLOOP: LXI SP,100H ;SET STACK POINTER.
LXI H,BDOS ;CP/M STARTS HERE.
MVI D,NSECTS ;NUMBER OF SECTORS TO READ.
MVI C,2 ;SECTOR NUMBER.
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.
IF NOT PERSCI AND NOT DUBSID
MVI A,53H ;STEP COMMAND.
OUT DCOM ;ISSUE IT.
IN WAIT ;WAIT UNTIL DONE.
ENDIF
IF PERSCI AND NOT DUBSID
MVI A,50H ;INCREMENT TRACK
OUT DCOM ;REGISTER.
IN WAIT ;WAIT FOR INTRQ.
MVI A,1 ;STEP
OUT DCONT ;PERSCI.
MVI A,72H ;SWITCH WAIT FOR
OUT DCONT ;SEEK COMPLETE.
IN WAIT ;WAIT.
MVI A,0F2H ;SWITCH WAIT
OUT DCONT ;BACK.
ENDIF
IF DUBSID ;IF DOUBLE SIDED SYSTEM.
MVI A,0B2H ;SIDE SELECT COMMAND.
OUT DCONT ;ISSUE IT.
ENDIF
MVI C,1 ;SECTOR NUMBER.
JMP RNTRK ;READ NEXT TRACK.
READ: OUT SECT ;SET SECTOR REGISTER.
CALL CHECK ;CHECK FOR ERROR.
MVI A,88H ;COMMAND FOR READ.
ORA B ;GET HEAD LOAD BIT.
OUT DCOM ;ISSUE COMMAND.
RLOOP: IN WAIT ;WAIT FOR DRQ.
ORA A ;SET FLAGS.
JP CHECK ;JUMP IF DONE.
IN DATA ;READ DATA.
MOV M,A ;PUT IN MEMORY.
INX H ;INCREMENT POINTER.
JMP RLOOP ;LOOP UNTIL DONE.
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.
CMA ;INVERT AND SEND
OUT 0FFH ;TO FRONT PANEL.
HERE: JMP HERE ;LOOP.
ORG 7DH ;PUT JUMP HERE.
RST 0 ;JUMP INTO BOOT.
NOP
DB 020H ;INDICATE SD/SS 128 BYTE
; SECTORS.
EC: END ;END OF BOOT.