	title	'Boot loader module for CP/M 3.0'

true equ -1
false equ not true

TEST	EQU	TRUE

IF	NOT TEST
banked	equ true
ENDIF

IF	TEST
BANKED	EQU	FALSE
ENDIF

	PUBLIC	SCBPTR,SCBSET
	public	?init,?ldccp,?rlccp,?time
	extrn	?pmsg,?conin
	extrn	@civec,@covec,@aivec,@aovec,@lovec
	extrn 	@cbnk,?bnksl
	EXTRN	T20MS

	maclib ports
	maclib z80

bdos	equ 5

	if banked
tpa$bank	equ 1
	else
tpa$bank	equ 0
	endif

	dseg	; init done from banked memory

?init:
	lxi h,08000h ! shld @civec ! shld @covec	; assign console to CRT:
	lxi h,04000h ! shld @lovec 			; assign printer to LPT:

IF	NOT TEST
	lxi h,02000h ! shld @aivec ! shld @aovec	; assign AUX to CRT1:
	lxi h,init$table ! call out$blocks	; set up misc hardware
ENDIF

	lxi h,signon$msg ! call ?pmsg		; print signon message
	ret	

IF	NOT TEST
out$blocks:
	mov a,m ! ora a ! rz ! mov b,a
	inx h ! mov c,m ! inx h
	outir
	jmp out$blocks
ENDIF


	cseg	; boot loading most be done from resident memory
	
    ;	This version of the boot loader loads the CCP from a file
    ;	called CCP.COM on the system drive (A:).

IF	TEST
?RLCCP:
ENDIF

?ldccp:
	; First time, load the A:CCP.COM file into TPA
	xra a ! sta ccp$fcb+15		; zero extent
	lxi h,0 ! shld fcb$nr		; start at beginning of file
	lxi d,ccp$fcb ! call open	; open file containing CCP
	inr a ! jz no$CCP		; error if no file...
	lxi d,0100h ! call setdma	; start of TPA
	lxi d,128 ! call setmulti	; allow up to 16k bytes
	lxi d,ccp$fcb ! call read	; load the thing
					; now,

IF	TEST
	RET				; CCP IMMER VOM FILE LADEN
ENDIF

IF	NOT TEST
					;   copy CCP to bank 0 for reloading
	lxi h,0100h ! lxi b,0C80h	; clone 3K, just in case
	lda @cbnk ! push psw		; save current bank
ld$1:
	mvi a,tpa$bank ! call ?bnksl	; select TPA
	mov a,m ! push psw		; get a byte
	mvi a,2 ! call ?bnksl		; select extra bank
	pop psw ! mov m,a		; save the byte
	inx h ! dcx b			; bump pointer, drop count
	mov a,b ! ora c			; test for done
	jnz ld$1
	pop psw ! call ?bnksl		; restore original bank
	ret
ENDIF

no$CCP:			; here if we couldn't find the file
	lxi h,ccp$msg ! call ?pmsg	; report this...
	call ?conin			; get a response
	jmp ?ldccp			; and try again

IF	NOT TEST
?rlccp:
	lxi h,0100h ! lxi b,0C00h	; clone 3K
rl$1:
	mvi a,2 ! call ?bnksl		; select extra bank
	mov a,m ! push psw		; get a byte
	mvi a,tpa$bank ! call ?bnksl	; select TPA
	pop psw ! mov m,a		; save the byte
	inx h ! dcx b			; bump pointer, drop count
	mov a,b ! ora c			; test for done
	jnz rl$1
	ret
ENDIF

    ; No external clock.
?time:
	; EINBINDUNG DER ZEITANZZEIGE  DIREKT IM SCB
	; HIER WIRD NUR BEI TIME SET DER 20ms-ZAEHLER RUECKGESETZT

	MOV	A,C
	INR	A
	RNZ		; GET TIME
	STA	T20MS	; SET TIME
	ret

	; CP/M BDOS Function Interfaces

open:
	mvi c,15 ! jmp bdos		; open file control block

setdma:
	mvi c,26 ! jmp bdos		; set data transfer address

setmulti:
	mvi c,44 ! jmp bdos		; set record count

read:
	mvi c,20 ! jmp bdos		; read records

SCBSET:
	MVI C,49 ! JMP BDOS		; GET/SET SCB

SCBPTR:	DB	4CH			; DRIVE SEARCH CHAIN
	DB	0FEH			; SET WORD
	DW	0100H			; CURRENT DRIVE, THEN A

signon$msg	db   1BH,97H,80H,13,10,'CP/M Version 3.1 for PC 1715',13,10,0

ccp$msg		db	13,10,'BIOS Err on A: No CCP.COM file',0


ccp$fcb		db	1,'CCP     ','COM',0,0,0,0
		ds	16
fcb$nr		db	0,0,0

IF	NOT TEST
init$table	db	3,p$zpio$3a,0CFh,0FFh,07h	; set up config port
		db	3,p$zpio$3b,0CFh,000h,07h	; set up bank port
		db	1,p$bank$select,0	; select bank 0
		db	0			; end of init$table
ENDIF

	end
