		subtitle	"< SYS0 IPL - DOS-initialization code & welcome message >"
		newpage
		scope

;		ORG	zspace.LIBRARY$
		
DOSINIT:	EQU     $
	
; Get <SYSGEN> status and update menu. This menu item is then used as a flag in IPL.

		ld	a,'y'
		ld	(SYSGN$),a
		ld	a,(ZERO$)
		or	a			; Test if 0?
		IF_EQ_BRANCH	CK_BRK
		ld	a,'n'
		ld	(SYSGN$),a

; Check is BREAK key disabled.

CK_BRK		ld	a,'y'
		ld	(brkflg$),a
		LD	HL,INBUF$
		LD	A,(HL)			; Pt to 1st byte of AUTO
		CP	'*'			; BREAK disable?
		IF_NE_BRANCH	CKAUTO		; Go if BREAK enabled.
		ld	a,'n'
		ld	(brkflg$),a
		ld	a,(zSFLAG$)		; Get systems flag.
		or	00010000b		; Disable break key.
		ld	(zSFLAG$),a		; Store it back.
		INC	HL
			
; Check on any AUTO command.							;

CKAUTO		ld	a,'y'
		ld	(autoflg$),a
		LD	A,(HL)			; Any AUTO command?
		CP	CR.asc			; None if equal.
		IF_NE_BRANCH	BERTDATE	; No AUTO command, skip setting flag to 'y'.
		ld	a,'n'
		ld	(autoflg$),a
		MVC	spaceout$,autoflg$+2,70
		MVC	no_auto$,autoflg$+2,17

; @@@@@@    Display welcome screen.	@@@@@@

BERTDATE	DATE.get	BERTSAYS+7		; Put current date in menu.
		TIME.get	BERTSAYS+21		; Put current time in menu.
		MVC	PAKNAM$,paknam$,15	; Move installation name from PAGE4.

; Get AUTO command if any, test if BREAK flag enabled/disabled. If 1st char * then disable.

		ld	hl,INBUF$		; Point to buffer with auto command if any.
		ld	a,(hl)			; Get 1st byte.
		inc	hl
		push	hl
		cp	'*'			; Turn BREAK off?
		BREAK.disable			; Turn BREAK off, this macro only uses HL register.
		IF_EQ_BRANCH	sav_point	; If yes, skip turning on?
		BREAK.enable
		MVC	SYSGN0$,CFGFCB$,6	; Setup default filename to load CONFIG/SYS.
		pop	hl
		dec	hl			; Bump pointer +1.
sav_point	ld	(HLsav),hl		; Save pointer to command buffer.

		ld	a,(quiet_default_flg)	; Get byte operator patched as starting terminal (default is 4).
		and	00000111b		; Get lower nibble.
		add	'0'			; Convert to ASCII.
		ld	(default_t),a		; Store default starting terminal in menu screen.

		ld	a,(quiet_default_flg)	; Get quiet/default IPL code.
		bit	6,a			; Is networking on?
		IF_EQ_BRANCH ipl_chk_quiet	; Bypass if quiet off.		

		call query_server		; Get server parameters.
		call bind_server		; Bind server & client (me).

ipl_chk_quiet	ld	a,(quiet_default_flg)	; Get quiet/default IPL code.
		and	10000000b		; Isolate quiet flag.
		IF_NE_GOTO default_ipl	; Bypass if quiet off.


main_ipl_menu	DATE.get BERTSAYS+7		; Put current date in menu.
		TIME.get BERTSAYS+21		; Put current time in menu.

		GOSUB	scrolloff

		PUMP	DEVICE.console,BOOTMENU	; Display main IPL menu.

inqlp:		GOSUB	getchar

		cp	ESC.asc			; Did they hit escape?
		IF_EQ_GOTO	main_ipl_menu	; If YES refresh screen.

		cp	'/'
		IF_EQ_GOSUB	test1

		cp	'+'
		IF_EQ_GOSUB	test2

		cp	'*'
		IF_EQ_GOSUB	test3

		cp	'-'
		IF_EQ_GOSUB	test4

		cp	'='
		IF_EQ_GOSUB	test5

		cp	'0'
		IF_EQ_GOTO	default_ipl

		IF_GT_BRANCH	inqlp		; If 0>key then it is not 0-9.

		cp	'1'			; Run updates.
		IF_EQ_GOTO	notimp

		cp	'2'
		IF_EQ_GOTO	safe_ipl	; Safe mode prompts for load sysgen, auto command etc.

		cp	'3'
		IF_EQ_GOTO	BIT_IPL		; BIT initialization.

		cp	'4'
		IF_EQ_GOTO	RTC_IPL		; RTC initialization.

		cp	'5'
		IF_EQ_GOTO	editslice	; Display/Edit Slice data.

		cp	'd'
		IF_EQ_GOSUB	set_terminal	; User wants change default setting for 
		cp	'D'
		IF_EQ_GOSUB	set_terminal	; default startup type.

		cp	'n'
		IF_EQ_GOSUB	net_utils	; Network utils.	
		cp	'N'
		IF_EQ_GOSUB	net_utils	; Network utils.

		cp	'x'
		IF_EQ_GOTO	reboot		; Call in and IPL CP/M.	
		cp	'X'
		IF_EQ_GOTO	reboot		; Call in and IPL CP/M.	

		GOTO	main_ipl_menu

; Final initialization code.

BIT_IPL		ld	a,'5'
		ld	(default_t),a		; Set to 0, $BIT.
		
default_ipl	ld	a,'n'			; Tell program this is NOT a SAFE start.
		ld	(safeipl$),a		; Initialize safe IPL flag to no.

		GOSUB	scrolloff

		ld	a,(default_t)		; Get default value for start...User can patch zRST00+3 to set default.

set_term	GOSUB	term_setup

		BRANCH	start_bkgnd		; Start background processing.

; Setup SAFE IPL session.
; Set safeipl$ to y.
; GOSUB to query user for terminal @set_terminal.
; set_terminal allows user to select terminal type for this session. 

safe_ipl	ld	a,'y'
		ld	(safeipl$),a		; Set safe IPL flag to YES.

; User is requesting a SAFE start.
; SAFE start allows operator to pick terminal type for session.
; GOSUB set_terminal asks operator to select which terminal.

		GOSUB	set_terminal		; Get & set terminal type for connection session.

; We are executing SAFE start, prompt if we should start background processing.

		GOSUB	scrolloff			; Clean screen up.
		
		PUMP	DEVICE.console,crlf
		PUMP	DEVICE.console,stbgrnd$		; Ask operator if we start background processing.		
		GOSUB	GET.yn				; Get response.
		cp	'y'
		IF_NE_GOTO	test_sysgen		; If answer if no, skip starting background tasks.


;     < < < < <  ****  > > > >  S E T U P   I N T E R R U P T   H A N D L E R  < < < <  ****  > > > > >


start_bkgnd	PUMP	DEVICE.console,crlf

		ld	a,(PFLAG$)			; Determine which processor we are on.
		sra	a				; Unpack it.
		cp	01h				; Is it a 91?
		IF_NE_BRANCH	nota91			; Bypass f91 code for PRT1 enable.

; Setup interrupt table for f91 processor.

		MVC	f91INTERRUPT.table,INTERRUPT.handler+40h,192	; Move interrupt table for f91 model.
		ld	hl,INTERRUPT.handler >> 8	; Get upper 8 bits of vector table.
		ld	i,hl				; Put upper 8 bits of table in I register.

; Enable 60HZ real time interrupts using PRT1.INTERRUPT.handler+40h

		in0	a,(TMR1_IIR)			; Read to reset.
		in0	a,(TMR1_CTL)			; Read to reset any pending interrupt.

		ld	a,01				; Enable interrupt at end of count.
		out0	(TMR1_IER),a			; IRQ EOC EN.

		in0	a,(TMR1_CTL)			; Get platform specific bits 7,6,5,4,3.
		and	11111000b			; Mask out preset bits.
		or	00000111b			; TIM_CONT,RLD,TIM_EN, enable PRT1 timer for eZ80f91.
		out0	(TMR1_CTL),a			; Timer is now loaded & counting. Waiting for EI.
		BRANCH	EN_IE				; Next step, interrupts and timwer on.	

nota91		MVC	f92INTERRUPT.table,INTERRUPT.handler,96	; Move interrupt table for f92 model chip.

; Setup PRT1 for eZ80f92 processor.

		ld	a,HIGH(INTERRUPT.handler)		; Setup internal interrupt register to interrupt table.
		ld	i,a

; Winner winner time for a stripper.

		in0	a,(f92_TMR1_CTL)			; Read & reset any pending interrupts.
		and	00001100b				; Strip her bits marked wit 0.
		or	01010011b				; Lets stuff da stripped-->Enbl, cont, using platform specific divisor.
		out0	(f92_TMR1_CTL),a			; Timer1 is now loaded & counting.

; Setup to enable interrupts during final phases of IPL.
; This phase of code is common to all processor platforms.

EN_IE		ei						; Enable interrupts, start backgroud task processing.
		
test_sysgen	ld	a,(safeipl$)				; Get safe$ flag.
		cp	'y'					; Are we starting in safe mode?
		IF_NE_GOTO load_sysgen				; Bypass asking if we load, just load.

		PUMP	DEVICE.console,ldSYSGN$			; Test if loading sysgen SYSGEN file needed.
		call	GET.yn					; Get response.
		cp	'y'
		IF_NE_GOTO	start_int			; If answer if no, skip loading systen & move to next step.

; SAFE start will now prompt loading of SYSGEN?
; Prompt operator if SYSGEN should be loaded?
; If NO, proceed directly to testing if background processing should be started.

		GOSUB	scrolloff
		PUMP	DEVICE.console,whichsysmsg$
		PUMP	DEVICE.console,crlf
		PUMP	DEVICE.console,pick_config$
		INPUT_U.str	CFGFCB$,6			; Get user defined CONFIG filename.
		cp	CR.asc					; Did it terminate with a CR?
		IF_EQ_BRANCH	ensysgen			; Operator pressed ENTER thus change.
		MVC	SYSGN0$,CFGFCB$,6			; filename to default CONFIG/SYS.
ensysgen	xor	a
		ld	(ZERO$),a				; Turn load sysgen on.			
load_sysgen	ld	a,(ZERO$)
		or	a					; Test if 0?
		IF_NE_GOTO	start_int

		GOSUB	scrolloff
		MVC	sysgener,sysgmsg,12			; Setup to show error if it dont load.
		MVC	CFGFCB$,sysgmsg,6
		MVC	CFGFCB$,lding$+10,6
		MVC	CONFIG$,sysgmsg,12			; Put sysgen message in LOGO splash screen.
		PUMP 	DEVICE.console,lding$			; Display sysgen file being loaded.

		MVC	DCT0$,savedct,80			; Save DCT before sysgen is loaded.

		LD	DE,CFGFCB$				; Set up to load config.
		GOSUB	zLOAD					; Go to load config.
	 	IF_NE_GOTO	test_sysgen			; error loading sysgen - NZ means error loading.

		MVC	savedct,DCT0$,80
		PUMP	DEVICE.console,ldingdn$			; Show file sysgen downloaded.

start_int	PUMP	DEVICE.console,exinitial$		; Tell operator we are calling initializing chain.
		GOSUB	zICNFG					; Here we start initilization chain.

		PUMP	DEVICE.console,initialdne$		; Tell operator initialization done.
		
		DELAY	75					; Let this awesumness settle in a bit on user viewing display ;-)

		PUMP	DEVICE.console,crlf
		PUMP	DEVICE.console,bkgrd_start$		; Tell em starting task processor on console.

		DELAY	75

		ld	d,100					; MAX retries testing if real-time running.
ck_start	ei						; Will change to EI if background starts, see above.
		ld	bc,0
waitonint	inc	bc					; BC = BC + 1.
		ld	a,(int_tmr1_cnt)			; Get interrupt counter.
		bit	7,a					; wait for about 128 interations.
		IF_NE_BRANCH	report_start			; Loop until we detect a 80 in LSB of counter.
		xor	a					; Check registers B & C. 
		cp	b					; When both registers = 0 at same time
		IF_NE_BRANCH	waitonint			; we have looped and tested interrupt counter
		cp	c					; 65535 times. If counter has not reached 80h by then
		IF_NE_BRANCH	waitonint			; PRT1 must not be running.
		dec	d					; Loop testing d times.
		IF_NE_BRANCH	ck_start			; Continue testing if PRT has started.

report_fail	PUMP	DEVICE.console,bkgrd_fail$		; PRT1 failed to start, tell operator background did not start.
		BRANCH	start_trsdos

report_start	PUMP	DEVICE.console,bkgrd_run$		; Tell operator background running.

		DELAY	75					; Let this awesumness settle in a bit on user viewing display ;-)