; init/asm
*TITLE	'<DOS+II Cold start initialization>'
;
;	MISCELLANEOUS EQUIVALENCES
;
ESC	EQU	27		;HOME/CLS
CR	EQU	13		;ASCII CR
VDLIN	EQU	9		;VIDEO LINE ROUTINE
SVC	EQU	8		;EXECUTE SVC
DREAD$	EQU	3		;read data sector
SREAD$	EQU	6		;read system sector
;
IVEC	EQU	70H		;IM2 VECTOR
BUFER1	EQU	1C00H		;use low ovly as buffer
BUFER2	EQU	2500H		;DCT data
;
*EJECT
;	SYSTEM INITIALIZATION
;
	ORG	1C00H		;LOW OVERLAY
;
START	DI			;KILL INT
	LD	SP,STACK	;INIT STACK
	IM	2		;MODE II
	LD	A,PAGE0<-8	;MSB INT VECTOR
	LD	I,A		;SET INT VECTOR
;
;	LOCATE TOP OF MEMORY
;
	LD	HL,-1		;HIGHEST ADD
;
START1	LD	A,(HL)		;GET BYTE
	CPL			;INVERT
	LD	(HL),A		;SAVE
	CP	(HL)		;ANY MEMORY?
	CPL			;RESTORE
	LD	(HL),A		;RESTORE
	JR	Z,START2	;IF YES
	LD	A,H		;GET ADDRESS
	SUB	20H		;8K BLOCKS
	LD	H,A		;NEW ADDRESS
	JR	START1		;TIL DONE
;
START2	LD	(DATAK7),HL	;TOP FREE MEMORY
	LD	(DATAK8),HL	;TOP PHY MEMORY
;
;	INITIALIZE SYSTEM DCT
;
	LD	HL,BUFER2+3	;HL => DCT INFO
	BIT	5,(HL)		;HD BOOT?
	LD	DE,DCT0+13	;DE => DCT+13
	LD	BC,10		;INFO LEN
	LDIR			;MOVE!
	JR	Z,START3	;ALL OK
	LD	IY,DCT0 	;IY => DCT
	SET	5,(IY+5)	;FLAG HD
	LD	(IY+6),0	;DEFAULT STEP
	LD	A,8		;1 LESS DEVICE
	LD	(IDATA),A	;TELL INIT
;
;	INITIALIZE SUPPORT CHIPS
;
START3	LD	HL,IDATA	;INIT DATA
	LD	E,(HL)		;DEVICE COUNT
	INC	HL		;NEXT
START4	LD	B,(HL)		;DEVICE ADDRESS
	INC	HL		;NEXT
	LD	C,(HL)		;COUNT
	INC	HL		;NEXT
	OTIR			;DO IT!
	DEC	E		;DONE?
	JR	NZ,START4	;TIL DONE
;
;	INITIALIZE NMI/INT ROUTINES
;
	LD	A,(VMASK)	;VIDEO/RTC MASK
	OUT	(LBANK),A	;ENABLE RTC
	IN	A,(RDKBD)	;CLEAR KBD INT
	EI
;
;	clear video and fetch key
;
	LD	B,ESC		;CLS code
	CALL	DSP		;display
;
	CALL	KBD		;fetch a key
	JR	Z,$+4		;yes, save it
	LD	B,0		;mask off bits
	LD	A,B		;fetch key
	CALL	UCASE		;make it upper case
	LD	(KEYSAVE),A	;save the key
	JP	INTMORE 	;continue!
;
*EJECT
;	INIT DATA FOR Z80 PIO
;
IDATA	DEFB	9		;DEVICE COUNT
;
	DEFB	5		;DATA COUNT
	DEFB	PIOAC		;PIOA CONFIG
	DEFB	000H		;INT VECTOR
	DEFB	0CFH		;BIT MODE
	DEFB	0F7H		;I/O MASK
	DEFB	037H		;INT OFF
	DEFB	0FEH		;INT MASK
;
	DEFB	3		;DATA COUNT
	DEFB	PIOBC		;PIOB CONFIG
	DEFB	000H		;INT VECTOR
	DEFB	00FH		;OUTPUT MODE
	DEFB	007H		;NO INT
;
;	INIT DATA FOR Z80 SIO
;
	DEFB	9		;DATA COUNT
	DEFB	SIOAC		;DEVICE ADRESS
	DEFB	18H		;CHANNEL RESET
	DEFB	4		;WR4
	DEFB	44H		;X16,S=1
	DEFB	3		;WR3
	DEFB	0E1H		;W=8,AUTO,RX
	DEFB	5		;WR5
	DEFB	0EAH		;DTR,W=8,TX,RTS
	DEFB	1+10H		;RES INT,WR1
	DEFB	18H		;INT ON ALL RX CHAR
;
	DEFB	11		;DATA COUNT
	DEFB	SIOBC		;DEVICE ADRESS
	DEFB	18H		;CHANNEL RESET
	DEFB	4		;WR4
	DEFB	44H		;X16,S=1
	DEFB	3		;WR3
	DEFB	0E1H		;W=8,AUTO,RX
	DEFB	5		;WR5
	DEFB	0EAH		;DTR,W=7,TX,RTS
	DEFB	2		;WR2
	DEFB	IVEC		;INT VECTOR
	DEFB	1+10H		;RES INT,WR1
	DEFB	1CH		;INT ON ALL RX CHAR
;
;	INIT DATA FOR Z80 CTC
;
	DEFB	3		;DATA COUNT
	DEFB	CTC0		;DEVICE ADDRESS
	DEFB	07H		;RESET,TC FOLLOWS
	DEFB	34H		;TIME CONSTANT 300 BAUD
	DEFB	IVEC+16 	;INT VECTOR
;
	DEFB	2		;DATA COUNT
	DEFB	CTC1		;DEVICE ADDRESS
	DEFB	07H		;RESET,TC FOLLOWS
	DEFB	34H		;TIME CONSTANT 300 BAUD
;
	DEFB	2		;DATA COUNT
	DEFB	CTC2		;DEVICE ADDRESS
	DEFB	07H		;RESET,TC FOLLOWS
	DEFB	34H		;TIME CONSTANT 300 BAUD
;
	DEFB	2		;DATA COUNT
	DEFB	CTC3		;DEVICE ADDRESS
	DEFB	0C7H		;RESET,TC FOLLOWS
	DEFB	01H		;TIME CONSTANT
;
;	INIT DATA FOR HD IO
;
	DEFB	3		;DATA COUNT
	DEFB	0C1H		;DEVICE ADDRESS
	DEFB	00H
	DEFB	10H
	DEFB	0CH
;
;
;	block of LOGO data here (max 5 pages)
;	insert graphic portion of display
;
LOGO2	EQU	$		;start
;
	BYTES	8,1EH
	BYTES	2,20H
	BYTES	8,1EH
	BYTES	1,20H
	BYTES	7,1EH
	BYTES	1,20H
	BYTES	9,1EH
	BYTES	1,20H
	BYTES	5,1EH
	BYTES	4,20H
	BYTES	5,1EH
	BYTES	1,20H
	BYTES	5,1EH
	BYTES	1,20H
	BYTES	7,1EH
	BYTES	4,20H
	BYTES	11,1EH
;
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	6,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	6,20H
	BYTES	3,1EH
	BYTES	3,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	10,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
;
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	7,1EH
	BYTES	2,20H
	BYTES	8,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	6,20H
	BYTES	3,1EH
	BYTES	3,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	7,1EH
	BYTES	6,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
;
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	5,20H
	BYTES	3,1EH
	BYTES	2,20H
	BYTES	3,1EH
	BYTES	7,20H
	BYTES	3,1EH
	BYTES	3,20H
	BYTES	2,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	3,20H
	BYTES	3,1EH
	BYTES	6,20H
	BYTES	3,1EH
	BYTES	6,20H
	BYTES	3,1EH
	BYTES	1,20H
	BYTES	3,1EH
	BYTES	2,20H
;
	BYTES	8,1EH
	BYTES	2,20H
	BYTES	8,1EH
	BYTES	1,20H
	BYTES	7,1EH
	BYTES	1,20H
	BYTES	5,1EH
	BYTES	5,20H
	BYTES	9,1EH
	BYTES	1,20H
	BYTES	9,1EH
	BYTES	2,20H
	BYTES	7,1EH
	BYTES	4,20H
	BYTES	11,1EH
;
LOGO2L	EQU	$-LOGO2
;
*EJECT
;
;	ASSHOLE foolin with our stuff?
;
	ORG	2200H		;high overlay area
;
INTMORE LD	HL,LOGO1	;checksum the header
	LD	BC,LOGO111<8+0	;length + checksum
INTCKSM LD	A,(HL)		;get a byte
	ADD	A,C		;add to checksum
	LD	C,A		;put it back
	INC	HL		;bump pointer
	DJNZ	INTCKSM 	;check it all
	CP	5AH		;is it OK?
	JR	Z,INTCKOK	;yes, go!
	DI			;turn off interrupts
	JP	$		;just hold here
;
;	read in control information
;
INTCKOK LD	DE,BUFER2+10H	;time/date/logo data
	LD	HL,FLAG 	;flag byte
	LD	(HL),0		;turn 'em off
;
	LD	A,(DE)		;get a byte
	INC	A		;date prompt?
	JR	NZ,GOCKLO	;nope, skip
	SET	7,(HL)		;ask for date
;
GOCKLO	INC	E		;next byte
	LD	A,(DE)		;get it
	INC	A		;logo display?
	JR	NZ,GOCKDA	;check time
	SET	6,(HL)		;display logo
;
GOCKDA	INC	E		;next byte
	LD	A,(DE)		;fetch it
	INC	A		;time prompt?
	JR	NZ,READMR	;go if done
	SET	5,(HL)		;set time prompt
;
;	display logo blocks
;
READMR	LD	HL,LOGO1	;block 1 (text)
	LD	BC,LOGO1L<8+CR	;len + term
	CALL	VDLINE		;display it
;
	LD	A,(FLAG)	;get flag
	AND	40H		;LOGO?
	JR	Z,CKDATE	;don't display it
;
	LD	HL,LOGO2	;graphic logo data
	LD	BC,4<8+0	;row + column to start
	LD	DE,80<8+5	;row length + # rows
;
LOGD1	CALL	VDGRAF		;display row of graphics
	PUSH	BC		;save cursor
	LD	BC,80		;length of video line
	ADD	HL,BC		;new data offset
	POP	BC		;restore cursor
	INC	B		;bump row position
	DEC	E		;less row counter
	JR	NZ,LOGD1	;finish all 5
;
	LD	B,CR		;send C/R
	CALL	DSP		;send C/R
;
*EJECT
;	check for date input
;
CKDATE	LD	A,(FLAG)	;get flag
	AND	80H		;DATE?
	JR	Z,VALDATE	;nope, valid date?
;
;	prompt for DATE$
;
GETDATE LD	HL,DATEPMT	;prompt
	LD	BC,DATEPMTL<8+11 ;len + term
	LD	DE,KEYBUFF	;keyboard buffer
	CALL	VIDKEY		;fetch/display
	EX	DE,HL		;swap
	JR	NZ,VALDATE	;error, forget it
	JR	C,VALDATE	;break, don't clear it
;
;	fetch the data from the string
;
	LD	B,1		;command
	CALL	DATE		;load it
	JR	NZ,GETDATE	;error, ask again
;
;	check for valid date field in DATE$
;
VALDATE LD	HL,DATE$	;start of data
	LD	A,(HL)		;get day of month
	CP	32		;too big?
	CALL	NC,CLRIT	;yes, clear it out
;
	LD	A,(DATE$+1)	;get month
	CP	13		;too big?
	CALL	NC,CLRIT	;yes, clear it out
;
	LD	A,(DATE$+2)	;get year
	CP	8		;too big?
	CALL	NC,CLRIT	;yes, clear it out
	LD	A,(DATE$)	;fetch day of month
	OR	A		;is it zero?
	JR	NZ,DOKK1	;nope, go!
	INC	A		;make it one
	LD	(DATE$),A	;put it back
DOKK1	LD	A,(DATE$+1)	;get month
	OR	A		;is it zero?
	JR	NZ,CKTIME	;nope, go!
	INC	A		;make it one
	LD	(DATE$+1),A	;put it back
;
*EJECT
;	check for time input
;
CKTIME	LD	A,(FLAG)	;get flag
	AND	20H		;time?
	JR	Z,VALTIME	;valid?
;
;	prompt for TIME$
;
GETTIME LD	HL,TIMEPMT	;prompt
	LD	BC,TIMEPMTL<8+9 ;len + term
	LD	DE,KEYBUFF	;keyboard buffer
	CALL	VIDKEY		;display & fetch
	EX	DE,HL		;swap
	JR	NZ,VALTIME	;error, can it!
	JR	C,VALTIME	;break, don't change
;
;	load data into TIME$
;
	LD	B,2		;command
	CALL	DATE		;load TIME$
	JR	NZ,GETTIME	;error, ask again
;
;	check for valid TIME$
;
VALTIME LD	HL,TIME$+1	;start of time
	LD	A,(HL)		;get seconds
	CP	61		;too big?
	CALL	NC,CLRIT	;yes, clear field
;
	LD	A,(TIME$+2)	;get minutes
	CP	61		;too big?
	CALL	NC,CLRIT	;yes, clear it
;
	LD	A,(TIME$+3)	;get hours
	CP	25		;too big?
	CALL	NC,CLRIT	;yes, clear
;
*EJECT
;	leave program entry point on stack
;
	LD	HL,CLRXIT	;'dos ready' level
	PUSH	HL		;save it
;
;	check for an auto command
;
	LD	E,0		;sector
	LD	B,E		;extended sector
	LD	HL,BUFER1	;buffer
	LD	C,E		;drive 0
	LD	A,SREAD$	;system read
	RST	10H		;read the GAT
	RET	NZ		;error, exit to DOS
;
;	check for any auto command
;
	LD	IY,BUFER1+0E0H	;start of data
	LD	A,(IY)		;get AUTO
	CP	CR		;nil?
	JR	NZ,INITGM	;nope, continue
;
;	no auto command, check for DEBUGGER
;
	LD	A,(KEYSAVE)	;get saved key
	CP	'D'             ;debugger?
	JP	Z,DEBUG 	;yes, go debug!
	RET			;else go dos ready
;
INITGM	LD	DE,KEYBUFF	;system key buffer
	LD	BC,32<8+0	;B=looper, C=counter
	LD	HL,FLAG 	;flag byte
	LD	(HL),C		;set to 0
;
PARAUTO LD	A,(IY)		;get a char
	CP	'!'             ;non-breakable?
	JR	Z,NOBRK 	;yes, set it up
	CP	'#'             ;no-display?
	JR	Z,NODSP 	;yes, set it up
	CP	CR		;C/R
	JR	NZ,PARPUT	;nope, continue
	LD	B,1		;force last char
	JR	PARBAK		;continue
;
PARPUT	LD	(DE),A		;put into buffer
	INC	DE		;bump pointer
	INC	C		;bump char count
PARBAK	INC	IY		;bump source
	DJNZ	PARAUTO 	;go for 32 chars
	LD	A,CR		;force in a C/R
	LD	(DE),A		;to the buffer
;
*EJECT
;	completed, check for to be displayed
;
	BIT	1,(HL)		;set from #
	LD	HL,KEYBUFF	;start of data
	JR	NZ,NOSHOW	;don't show it
	LD	A,(KEYSAVE)	;get boot-up key
	CP	CR		;override?
	JR	NZ,INITSHO	;nope, display it
	LD	A,(FLAG)	;get flag back
	BIT	0,A		;non-breakable
	JR	Z,NOSHOW	;breakable, go!
;
INITSHO INC	C		;check for nil
	DEC	C
	JR	Z,NOSHOW	;yes, finished
;
	INC	C		;length + carriage return
	LD	B,C		;get length
	LD	C,0		;terminator
	CALL	VDLINE		;display it
;
NOSHOW	LD	A,(FLAG)	;get flag byte
	AND	1		;bit 0 for no break?
	JP	NZ,DOSCMD	;yes, execute!
;
	LD	A,(KEYSAVE)	;get saved key
	CP	CR		;auto override?
	RET	Z		;yes, go dos ready
;
	LD	DE,DOSCMD	;executer on stack
	PUSH	DE		;to stack
	LD	A,0		;fetch power-up key
KEYSAVE EQU	$-1
	CP	'D'             ;go debug?
	RET	NZ		;nope go dos command
	JP	DEBUG		;go debug!
;
*EJECT
NOBRK	BIT	0,(HL)		;already set?
	JR	NZ,PARPUT	;ignore it
	SET	0,(HL)		;only allow it once
;
	LD	A,KDCB@ 	;get keyboard
	CALL	LOCDCB		;find it
	SET	6,(IX+5)	;turn off break key
	JR	PARBAK		;continue
;
NODSP	BIT	1,(HL)		;alread set?
	JR	NZ,PARPUT	;skip if yes
	SET	1,(HL)		;turn it on
	JR	PARBAK		;continue
CLRIT	LD	(HL),0		;load all 0's
	INC	HL
	LD	(HL),0
	INC	HL
	LD	(HL),0
	DEC	HL
	DEC	HL
	RET			;done
;
FLAG	DEFB	0		;for command interpret
;
*EJECT
;	MESSAGES AND TEXT STRINGS
;
LOGO1	DEFM	'DosPLUS II - '
	DEFM	'Series A.00 - '
	DEFM	'Disk Operating System '
	DEFM	'for Mod II and Z80 Mod 16'
	DEFB	CR
	DEFM	'(c)(p) Copyright 1982 '
	DEFM	'by MicroPower, Inc. - '
	DEFM	'ALL RIGHTS RESERVED'
LOGO111 EQU	$-LOGO1
	DEFM	' - Test Copy!'
	DEFB	CR
	DEFB	CR
	DEFB	CR
LOGO1L	EQU	$-LOGO1
;
DATEPMT DEFM	'Date: '
DATEPMTL EQU	$-DATEPMT
;
TIMEPMT DEFM	'Time: '
TIMEPMTL EQU	$-TIMEPMT
;
;
 