;
; 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.