;
; TARBELL ELECTRONICS
; CP/M 1.4 COLDSTART LOADER
; VERSION OF 3-22-'79/10-20-2010.
;
; 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	64	;MEMORY SIZE IN DECIMAL KB.	**
EXTRA	equ	false	;reserve extra 5 sectors	**
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.	**
;							**
;*********************************************************
;*********************************************************
;
c$disk	equ	4	;address of current logged disk
err$sts	equ	8

dsk$cmd 	equ 	0D0h 
dsk$sts 	equ 	0D0h 
dsk$drv		equ	0D1h ;drv
dsk$trkL	equ	0D2h ;trkLow
dsk$trkH	equ	0D3h ;trkHigh
dsk$secL	equ	0D4h ;secLow
dsk$secH	equ	0D5h ;secHigh
dsk$dmaL	equ	0D6h ;dmaLow
dsk$dmaH	equ	0D7h ;dmaHigh
dsk$sptL	equ	0D8h ;sptLow
dsk$sptH	equ	0D9h ;sptHigh

cmd$read	equ	1
cmd$write	equ	2
cmd$log		equ	4
cmd$fmt		equ	8

sec$sz	equ	128

;bios can be 512 (4 sectors) bytes
; or 1024+128 (9 sectors) + 384 unitialized
	if	extra		
CBASE	EQU  (MSIZE-17)*1024
NSECTS	EQU  51		;SECTORS OF CP/M.
	else
CBASE	EQU  (MSIZE-16)*1024
NSECTS	EQU  46		;SECTORS OF CP/M.
	endif
CPMB	EQU  CBASE+2900H;START OF CP/M.
BOOTE	EQU  CBASE+3E00H;COLD BOOT ENTRY POINT.
RTCNT	EQU  10		;NUMBER OF RETRYS.

	ORG  0		;START OF LOADER.

BOOT:	
BLOOP:	LXI  SP,100H	;SET STACK POINTER.
	xra	a
	out	dsk$trkL
	out	dsk$trkH
	out	dsk$secH
	out 	dsk$drv
	LXI  H,CPMB	;CP/M STARTS HERE.
	MVI  B,NSECTS	;NUMBER OF SECTORS TO READ.
	MVI  C,2	;SECTOR NUMBER.
RNTRK:	
	MOV  A,C	;SECTOR IN A.
RNSEC:	CALL READ	;READ FIRST SECTOR.
	DCR  B		;IF DONE,
	JZ   BOOTE	;GO TO CP/M.
	INR  C		;INCREMENT SECTOR COUNT.
	MOV  A,C	;DONE WITH
	CPI  SPT+1	;THIS TRACK?
	JC   RNSEC	;IF NOT, READ NEXT SECTOR.
	in	dsk$trkL
	inr	a
	out	dsk$trkL
	MVI  C,1	;SECTOR NUMBER.
	JMP  RNTRK	;READ NEXT TRACK.

;a=sector hl=dma bc=dont touch
READ
	out	dsk$secL	;store next sector
	mov	a,l
	out	dsk$dmaL
	mov	a,h
	out	dsk$dmaH
	mvi	a,cmd$read	;read
	out	dsk$cmd
	in	dsk$sts
	ana	a		;set flags(ccr)
	jnz	r$eror		;exit if error
	lxi	d,sec$sz	;sector size
	in	dsk$dmaL
	mov	l,a
	in	dsk$dmaH
	mov	h,a
	dad	d		;new buffer address 
	ret 

r$eror:	 sta	err$sts		;store error 
	 hlt			;halt
	

EC:	END		;END OF BOOT.
