	title	'Boot loader module for CP/M 3.0'
;************************************************
;	Initialization
;	Boot and Warmboot
;	Time and Date Support
;	This Module requires info-s Hardware
;	Banked Version 08/15/83
;	(c) Copyright by G.Krause 1983
;       Modified by  W.A. Kobler  KW831116
;************************************************

CBANK	EQU	0EEH		; CPU BANK REGISTER


	public	?init,?ldccp,?rlccp,?time
	extrn	?pmsg,?conin
	extrn	@civec,@covec,@aivec,@aovec,@lovec
	extrn 	@cbnk,?bnksl
	extrn   @DATE,@HOUR,@MIN,@SEC
	maclib 	ports
	maclib 	z80

bdos	equ 	5

	cseg

?init:
	EXX			; GET 2ND REGISTER SET
	MOV	A,B
	ORA	A		; TEST FOR V5/V4
	LXI	H,8000H		; V5
	JRZ	INIT01		; JUMP IF V5
	LXI	H,2000H		; V4
INIT01:
	shld 	@civec  
	shld 	@covec		; assign console 
	EXX
	lxi 	h,0800h  	; Mod. KW831116
	shld 	@lovec 		; assign printer 
	lxi 	h,2000h  	; Mod. KW831116
	shld 	@aivec  
	shld 	@aovec		; assign AUX 
	lxi 	h,signon$msg  
	call 	?pmsg		; print signon message
	MVI	C,00
 	CALL	?TIME
	ret	



;************************************************
;	This version of the boot loader loads 
;       the CCP from a file called CCP.COM on
;       the system drive (A:).
;************************************************ 
?rlccp:
	MVI	A,12H		; GET COPY OF CCP
	OUT	CBANK
	LXI	H,0B000H
	LXI	D,0100H
	LXI	B,0D00H
	LDIR
	LDA	@CBNK
	CALL	?BNKSL
	RET

?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
	DCR	A
	ora	a		; test for read error
	jnz	rderror
	MVI	A,21H		; LOAD BANK FOR CCP COPY
	LXI	H,0100H
	LXI	D,0B000H
	LXI	B,0D00H		
	OUT	CBANK
	LDIR
	LDA 	@CBNK
	CALL	?BNKSL
	ret

no$CCP:				; here if we couldn't find the file

	lxi 	h,ccp$msg  
	jr	comerr 
rderror:
	lxi	h,err$msg
comerr:
	call	?pmsg
	call	?conin
	jmp	?ldccp


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


signon$msç	
	dâ	13,10,13,10,'CP/Í 3 BANKED KW6580/2 320k   BIOS V 1.10'
	db      13,10,0

ccp$msg		
	db	13,10,'BIOS Err on A: No CCP.COM file',0DH,0AH
	DB	'Press any key to retry',0DH,0AH,0

err$msg	
	db	13,10,'Error during loading CCP.COM file',0DH,0AH
	DB	'Press any key to retry',0DH,0AH,0

ccp$fcb		
	db	1,'CCP     ','COM',0,0,0,0
	ds	16
fcb$nr		
	db	0,0,0

 
;************************************************
;	TIME AND DATE SUPPORT FOR M3000 
;	REAL TIME CLOCK CHIP
;************************************************
?TIME:
	SSPD	STSAVE
	LXI	SP,LSTACK
	XRA	A
	OUT	CBANK		; SET CPU BANK TO 0
	CALL	TIME1		; GO TO BANKED PART
	LDA	@CBNK
	ANI	0FH
	MOV	B,A
	SLAR	A
	SLAR	A
	SLAR 	A
	SLAR	A
	ORA	B
	OUT	CBANK
	LSPD	STSAVE
	RET
	DS	20H
LSTACK:	EQU	$
STSAVE: DW	00


;************************************************
;	RTC ROUTINES ARE BANKED
;************************************************
	DSEG
TIME1:
	XRA	A		; CLEAR A-REG
	ORA	C		; TEST FUNKTION
	JZ	RDTIME		; TIME FROM M3000 TO SCB
	INR	A	
	RNZ			; INVALID CALL RETURN

;************************************************
;	TIME FROM SCB TO THE M3000 CHIP
;************************************************
	MVI	A,78H		; SET INITIAL YEAR
	STA	YEAR		
	LHLD	@date		; COPY @DATE FOR
	shld	date		; INTERNAL USE
	MVI	E,1		; TIME FROM SCB TO M3000
TLOOP01:
	LHLD	Date
	mov	A,E
	CPI	03
	LXI	B,0367		  
	JRZ	TLOOP03		; JUMP IF LEAP-YEAR  
TLOOP02:
	DCX	B		; CORRECT FOR NORMAL YEAR
TLOOP03:
	XRA	A
	DSBC	BC
	JRC	TLOOP05		; JUMP IF LESS THAN 1 YEAR
	INR 	E		; MODIFY LEAP-YEAR COUNTER
	RES	2,E
	INX	H
     	SHLD	DATE
	LDA	YEAR		; INC YEAR FIELD
	ADI	01H		;
	DAA			;
	STA	YEAR		;
	JMP	TLOOP01
TLOOP05:			; DATE COUNT IS LESS THAN
       				; 1 FULL YEAR
	MOV	A,E
	CPI	03		; TEST LEAP-YEAR
	LXIX	SUBTAB1
	JRNZ	TLOOP6		; JUMP IF NO LEAP-YEAR
	LXIX	SUBTAB2
TLOOP6:
	LHLD	DATE		; DAYS IN THE YEAR
	MVI	B,-12		; COUNT VALUE
	MVI	D,00
MLOOP01:
	LDX	E,0		; LOAD SUBTRACT VALUE
	INR	E
	XRA	A
	DSBC	D		; SUBTRACT DAYS OF THE MONTH
	JRC	MFOUND
	INX	H
	SHLD	DATE		; SAVE REMAINIMG DAYS
	INXIX			; POINT TO NEXT MONTH
	INR	B		; REDUCE COUNT
	JR	MLOOP01
MFOUND:
	MVI	A,13		; CALCULATE MONTH
	ADD	B
	CPI	10
	JRC	MFOUND01 
	SUI	10
	ANI	0FH
	ORI	10H
MFOUND01:
	
	STA	MONTH
	LDA	DATE		; REMAINING DAY COUNT
	MOV	C,A
	MVI	B,00
	LXI	H,TRANS 
	DAD	B
	DCX	H
	MOV	A,M
	STA	DAY
	LDA	@SEC
	STA	SEC
	LDA     @MIN
	STA     MIN
	LDA	@HOUR
	STA	HOUR

	MVI	B,00
	LXI	D,SEC
LDCLOCK:
	LDAX	D		; LOAD DATA IN
	MOV	H,A		; THE M3000 CHIP
	SRAR	A
	SRAR	A
	SRAR	A
	SRAR	A
	MOV	L,A
	CALL	STORE
	MOV	A,B
	INR	B
	INX	D
	CPI	05
	JRNZ	LDCLOCK
	MVI	B,0FH		; SET WATCH RUN FLAG
	LXI	H,0100H
	CALL	STORE 
	RET       


;************************************************
;	READ OR STORE VALUES TO M3000
;************************************************
STORE:   
	CALL	SCLOCK
	OUTP	L
	OUTP	H
	RET
READCLK:
	CALL	SCLOCK
	INP	L		; VALUE IS RETURNED
	INP	H		; IN BCD FORMAT
	RET
SCLOCK:
	MVI	C,0ECH
	INP	A		; CHECK STATUS
	ANI	0FH
	ORA	A
	JRNZ	SCLOCK
	MVI	A,30
SCLOCK01:
	DCR	A
	JRNZ	SCLOCK01
	INP	A
	ANI	0FH
	ORA	A  
	JRNZ	SCLOCK
	OUTP	B		; POINT TO REG
	RET

;************************************************
;	READ TIME AND DATE FROM M300 AND 
;	UPDATE THE SCB FIELDS
;************************************************
RDTIME:
	LXI	H,0000
	SHLD	DATE
	MVI	B,00
	LXI	D,SEC
RTIME01:
	CALL	READCLK
	SLAR	L
	SLAR	L
	SLAR	L
	SLAR	L
	MOV	A,H
	ANI	0FH
	ORA	L
	STAX	D
	MOV	A,B
	INR	B
	INX	D
	CPI	05
	JRNZ	RTIME01

;************************************************
;	MOVE TIME TO SCB FIELDS
;************************************************
	LDA	SEC
	STA	@sec
	LDA	MIN
	STA	@MIN
	LDA	HOUR
	STA	@HOUR

;************************************************
;	CALCULATE DAY COUNT
;************************************************
	MVI	E,01
	XRA	A	
	LDA	YEAR
	SUI	78H		; SUBTRACT BASE YEAR
	DAA
	JZ 	MONTH00
	MOV	D,A
YEAR01:
	LHLD	DATE
	LXI	B,365
	MOV	A,E
	CPI	03
	JRNZ	YEAR02 
	INX	B
YEAR02:
	DAD	B
	SHLD	DATE
	INR	E
	RES	2,E
	MOV	A,D
	SUI	01H
	DAA	
	MOV	D,A
	JRNZ	YEAR01
MONTH00:
	MOV	A,E
	CPI	03
	LXIX	SUBTAB1
	JRNZ	MONTH01
	LXIX	SUBTAB2
MONTH01:
	LDA	MONTH
MONTH02:
	SUI     01H
	DAA	
	MOV	D,A
	ORA	A
	JRZ	DAY00 
	LHLD	DATE
	MVI	B,0
	LDX	C,0
	DAD	B		; ADD DAYS OF THE MONTH
	SHLD	DATE
	INXIX
	MOV	A,D
	JR 	MONTH02
DAY00:
	LDA	DAY
	ORA	A
	JRZ	DAY01
DAY02:
	LHLD	DATE
	INX	H
	SHLD 	DATE
	SUI	01H
	DAA
	JRNZ	DAY02
DAY01:
	LHLD	DATE
	SHLD	@DATE
	RET


SUBTAB1:
	DB	31,28,31,30,31,30,31,31,30,31,30,31
SUBTAB2:
	DB	31,29,31,30,31,30,31,31,30,31,30,31
TRANS:
	DB	01,02,03,04,05,06,07,08,09,10H,11H 
	DB	12H,13H,14H,15H,16H,17H,18H,19H,20H
	DB	21H,22H,23H,24H,25H,26H,27H,28H,29H
	DB	30H,31H

SECº   
	DB	00
MIN:	
	DB	00
HOUR:	
	DB	00
DAY:
	DB	01
MONTH:
	DB	01
YEAR:
	DB	78H
DATE:	
	DW	0000H
	
	END