
;--------------------------< S U B R O U T I N E S >--------------------------


cpu_dly		ld		a,(PFLAG$)			; Which processor we running on?
		sra		a
		cp		01h				; Is this a 91?
		IF_EQ_BRANCH	cpu_dly_91

cpu_dly_92	FOR		1,19,1				; Half the delay for a f92, its slower.
cpu_dly_92a	FOR		1,30000,1
		NEXT		cpu_dly_92a
		NEXT		cpu_dly_92
		RETURN
	
cpu_dly_91	FOR		1,37,1
cpu_dly_91a	FOR		1,30000,1
		NEXT		cpu_dly_91a

		IN0    		A,(UART0_LSR)			; Get status of data waiting?
		AND    		UART_DR     			; Char waiting?
		IF_NE_RETURN
		NEXT		cpu_dly_91
		RETURN

scrolloff	FOR	1,25,1
		PUMP	DEVICE.console,crlf
		NEXT	scrolloff
		RETURN

GET.yn		GOSUB	getchar					; Get users one character response.

		cp	DEL.asc					; User hit RUBOUT (shift del/delete)?
		IF_EQ_RETURN					; If yes return this key if yes.
		cp	ESC.asc					; User hit escape key?
		IF_EQ_RETURN					; If yes return this key if yes.
		cp	SOH.asc					; Test if user hit ctrl^a or HOME?
		IF_EQ_RETURN					; If yes return this key if yes.

		cp	'Y'					; Y reply?
		IF_EQ_BRANCH	cngYy				; Change to lower case.
		cp	'N'					; N reply?
		IF_EQ_BRANCH	cngNn				; Change to lower case.
		cp	'y'					; y reply?
		IF_EQ_BRANCH	clnup
		cp	'n'					; n reply?
		IF_EQ_BRANCH	clnup
		BRANCH	GET.yn					; Not a yes or no so get another key.
cngYy		ld	a,'y'					; Change to lower case.
		BRANCH	clnup

cngNn		ld	a,'n'					; Change to lower case.			
clnup		PUSH	AF
		PUMP 	DEVICE.console,crlf+1
		POP	af
		RETURN

getchar		IN0    	A,(UART0_LSR)				; Get status of data waiting?
		AND    	UART_DR     				; Char waiting?
		IF_EQ_BRANCH	getchar				; Make NZ, NO char waiting.
		IN0   	A,(UART0_RBR)				; Get byte from UART0.
		cp	a
		RETURN

delay		ld	b,0					; Delay a bit.
		ld	de,0h
dly_lp		dec	de
		ld	a,d
		or	e
		jr	nz,dly_lp
		djnz	delay+2
		RETURN

mounterr0	PUMP	DEVICE.console,mounterrmsg0
		jr	$					; If no root volume we cannot boot.
mounterr1	ret	;PUMP	DEVICE.console,mounterrmsg1
		ret						; Problems with data vol, go back and try continue.
nodirectort1	PUMP	DEVICE.console,nodirdrv0msg1
		jr	$
cant_ipl_data	PUMP	DEVICE.console,nobootdatamsg
		jr	$
not56fmt	PUMP	DEVICE.console,not56fmtmsg
		ret

notimp		PUMP	DEVICE.console,NOTIMPMENU		; Pump.
		GOSUB	getchar
		GOTO	main_ipl_menu


; Store ASCII representation of 24 bit value in main memu.
; Convert to packed BCD.
; Convert packed BCD to unpacked.
; Convert unpacked to ASCII.
; Trim leading 0's away.
; Stuff all these results in main menu.


cvt_24_ascii	ld		l,0			; Pack DE into 24 bit
		ld		h,e			; register combo.
		ld		e,d			; E:HL.

		PUSH		BC			; Save pointer to menu buffer.
		call		Alwin			; convert to packed BCD in DE:HL.
		pop		bc			; recover pointer to bootsiz$

		push		hl			; Needed for conversion		
		push		hl			; routines & stuffing menu.
		push		de


		ld		hl,bc			; Address to store ASCII result in string.

		ld		a,d			; Convert 2 packed BCD to ASCII digits and store at (HL).
		call		bin24ascii

		pop		de			; Recover digits.
		ld		a,e			; Get 3rd & 4th digit.
		call		bin24ascii

		pop		de			; Recover size.
		ld		a,d			; Convert 2 packed BCD to ASCII digits and store at (HL).
		call		bin24ascii

		pop		de			; Recover digits.
		ld		a,e			; Get 3rd & 4th digit.
		call		bin24ascii

		ld		hl,bc			; Scan this buffer.
		ld		b,8			; Scan 8 chars.
		call		trim_zeros		; Trim off leading zeros.

		ret

; Routine for converting a 24-bit binary number to decimal
; In: E:HL = 24-bit binary number (0-16777215)
; Out: DE:HL = 8 digit decimal form (packed BCD)
; Changes: AF, BC, DE, HL & IX


; Straight from my time-tested toolbox Smile If you want bigger numbers: let me know.
; I also have a ; routine that can do up to 64 bit numbers (20 digits decimal) and produces ready-for-printing result, 
; but it's quite a bit longer. Probably did it once just to see how easy it was to expand, or to have 
; something that can take anything you throw at it...
; by Alwin Henseler

Alwin:           LD C,E
                 PUSH HL
                 POP IX          ; input value in C:IX
                 LD HL,1
                 LD D,H
                 LD E,H          ; start value corresponding with 1st 1-bit
                 LD B,24         ; bitnr. being processed + 1

FIND1:           ADD IX,IX
                 RL C            ; shift bit 23-0 from C:IX into carry
                 JR C,NEXTBIT
                 DJNZ FIND1      ; find highest 1-bit

; All bits 0:
                 RES 0,L         ; least significant bit not 1 after all ..
                 RET

DBLLOOP:         LD A,L
                 ADD A,A
                 DAA
                 LD L,A
                 LD A,H
                 ADC A,A
                 DAA
                 LD H,A
                 LD A,E
                 ADC A,A
                 DAA
                 LD E,A
                 LD A,D
                 ADC A,A
                 DAA
                 LD D,A          ; double the value found so far
                 ADD IX,IX
                 RL C            ; shift next bit from C:IX into carry
                 JR NC,NEXTBIT   ; bit = 0 -> don't add 1 to the number
                 SET 0,L         ; bit = 1 -> add 1 to the number
NEXTBIT:         DJNZ DBLLOOP
                 RET

;--------------- snip -----------


bin24ascii	push	af		; Save binary copy for later.
		and	F0h		; Strip all but upper 4 bits.
		srl	a		; Shift right.
		srl	a
		srl	a
		srl	a
		call	cvtbinasc

		pop	af		; Recover original values.
		and	0Fh		; Strip out upper 4 bits.			


cvtbinasc	add	'0'		; Convert nibble to ASCII.
		ld	(hl),a		; Store it in buffer.
		inc	hl		; Bump pointer up by 1.
		ret

; routine to trim leading zeros from a string.
; B = char to check.

trim_zeros	ld	a,'0'		; ASCII zero.
		cp	(hl)		; HL points to buffer under test.
		ret	nz
		ld	(hl),SP.asc	; SPACE Stuff it.
		inc	hl
		djnz	trim_zeros
		dec	hl
		ld	(hl),'0'
		ret