;************************************************
;						*
;		ADVANCED MICRODIGITAL		*
;		    MONITOR PROM		*
;						*
;************************************************
	TITLE	ADVANGED MICRODIGITAL MONITOR PROM  Jan 07 1983 09:20
	.Z80
TRUE	EQU	0FFFFH			;DEFINE VALUE OF TRUE
FALSE	EQU	NOT TRUE		;DEFINE VALUE OF FALSE
TEST	EQU	false			;TRUE IF TEST RUN
SLAVE	EQU	FALSE			;TRUE IF MONITOR FOR SLAVE
;
	IF	TEST
ROM	EQU	100H			;BASE OF ROM
RAM	EQU	1000H			;BASE OF LOCAL RAM
	ELSE
	IF	SLAVE
ROM	EQU	0			;BASE OF ROM
RAM	EQU	0FE00H			;BASE OF LOCAL RAM
	ELSE
ROM	EQU	0F000H			;BASE OF ROM
RAM	EQU	0EE00H			;BASE OF LOCAL RAM
	ENDIF
	ENDIF

STACK	EQU	RAM+100			;STACK AREA
;
;	SYSTEM EQUATES
;
BKSP	EQU	08H			;BACKSPACE EQUATE
CR	EQU	0DH			;CARRAIGE RETURN
LF	EQU	0AH			;LINEFEED
ESC	EQU	1BH			;ESCAPE KEY
RUBOUT	EQU	7FH			;RUBOUT KEY
;
IOBASE	EQU	0
SER0D	EQU	IOBASE			;SERIAL PORT 0 DATA  
SER0S	EQU	IOBASE+1		;SERIAL PORT 0 STATUS
SER1D	EQU	IOBASE+2		;SERIAL	PORT 1 DATA  
SER1S	EQU	IOBASE+3		;SERIAL PORT 1 STATUS

	IF	SLAVE
SER2D	EQU	IOBASE+0CH		;SERIAL PORT 2 DATA
SER2S	EQU	IOBASE+0DH		;SERIAL PORT 2 STATUS
SER3D	EQU	IOBASE+0EH		;SERIAL	PORT 3 DATA
SER3S	EQU	IOBASE+0FH		;SERIAL PORT 3 STATUS
BAUDRT	EQU	IOBASE+10H		;BAUD RATE SELECT PORT
PIO0D	EQU	IOBASE+14H		;PARALLEL PORT 0 DATA
PIO1D	EQU	IOBASE+15H		;PARALLEL PORT 1 DATA
PIO0C	EQU	IOBASE+16H		;PARALLEL PORT 0 CONTROL
PIO1C	EQU	IOBASE+17H		;PARALLEL PORT 1 CONTROL
INTD	EQU	IOBASE+18H		;INTERRUPT CONTROLLER DATA PORT
INTS	EQU	IOBASE+19H		;INTERRUPT CONTROLLER STATUS PORT
LSSP@	EQU	IOBASE+1DH		;MEMORY CONTROL PORT
LDP@	EQU 	IOBASE+1EH		;SLAVE TO MASTER DATA PORT
LCSP@	EQU	IOBASE+1FH		;SLAVE TO MASTER CONTROL PORT

	ELSE

PIO0D	EQU	IOBASE+04H		;PARALLEL PORT 0 DATA
PIO1D	EQU	IOBASE+05H		;PARALLEL PORT 1 DATA
PIO0C	EQU	IOBASE+06H		;PARALLEL PORT 0 CONTROL
PIO1C	EQU	IOBASE+07H		;PARALLEL PORT 1 CONTROL
CTC0	EQU	IOBASE+08H		;CTC CHANNEL 0 PORT
CTC1	EQU	IOBASE+09H		;CTC CHANNEL 1 PORT
CTC2	EQU	IOBASE+0AH		;CTC CHANNEL 2 PORT
CTC3	EQU	IOBASE+0BH		;CTC CHANNEL 3 PORT
FDC	EQU	IOBASE+0CH		;FLOPPY DISK BASE ADDRESS
FDCTRK	EQU	FDC+1
FDCSEC	EQU	FDC+2
FDCDATA	EQU	FDC+3
WAIT	EQU	IOBASE+14H		;FLOPPY WAIT PORT & DRIVE SELECT
EXADD	EQU	IOBASE+15H		;EXTENDED ADDRESS I/O PORT
MEMCTL	EQU	IOBASE+16H		;MEMORY CONTROL PORT

;***   Port equates for HDC1001   ***
HDCBASE	EQU	070H		; Base of HDC1001
HDCDATA	EQU	HDCBASE		; Data port
WPC	EQU	HDCBASE+1	; Write precomp port
HDCERR	EQU	WPC		; Error port
SECNT	EQU	HDCBASE+2	; Sector count
SECNO	EQU	HDCBASE+3	; Sector number
CYLLO	EQU	HDCBASE+4	; Cylinder low
CYLHI	EQU	HDCBASE+5	; Cylinder high
SDH	EQU	HDCBASE+6	; Size/Drive/Head
COMND	EQU	HDCBASE+7	; Command register
STATUS	EQU	COMND		; Status register

;***   Command equates for HDC1001   ***
CREST	EQU	10H		; Restore command
CSEEK	EQU	70H		; Seek command
CREAD	EQU	20H		; Read sector command

;***   HDC1001 ECC selection ***
eccbit	equ	80h			;ecc command bit
ecc	equ	false			;set true to enable ecc

	ENDIF
;
	IF	SLAVE
SENSW	EQU	1			;SENSE SWITCH BIT
;
B50	EQU	0
B75	EQU	1
B110	EQU	2
B134	EQU	3
B150	EQU	4
B200	EQU	5
B300	EQU	6
B600	EQU	7
B1200	EQU	8
B1800	EQU	9
B2400	EQU	10
B3600	EQU	11
B4800	EQU	12
B7200	EQU	13
B9600	EQU	14
B19200	EQU	15
	ENDIF
;
;	STORAGE AREA
;
	DSEG
;	ORG	RAM			;RAM AREA
;
ECHO::	DS	1			;ECHO FLAG
FRSTIM::
	DS	1			;FIRST TIME THRU BOOT FLAG
ADR::	DS	2			;EXAMINE/MODIFY ADDRESS
hddsk:	ds	1			;hard disk available flag
;
;
;	MONITOR SUPPORT VECTORS
;
	CSEG
;	ORG	ROM
;
EXEC::	JP	BEGIN			;AND BEGIN
	JP	OUTPTY			;OUTPUT A CHARACTER FROM REG A
	JP	INPUT			;GET A CHAR. INTO REG A (NO ECHO)
	JP	INPUT0			;CHECK FOR KEY PUSHED..RET IF NONE
	JP	CHIN			;GET CHAR INTO A W/ ECHO,PARITY STRIP
	JP	MSG			;OUTPUT MESSAGE,-H,L. ZERO TERMIN.
	JP	CRET			;OUTPUT CR,LF,RUBOUT
	JP	SPACE			;OUTPUT ONE SPACE
	JP	THXN			;OUT B 3-0 OF'A'IN HEX(1 ASCII CHAR)
	JP	THXB			;OUT REG A IN ASCII-HEX (2 CHARS)
	JP	THXW			;OUTPUT H,L IN ASCII-HEX (4 CHARS)
	JP	GHXN			;GET HEX NIBBLE INTO REG A (B 3-0)
	JP	GHXB			;GET HEX BYTE INTO REG A (B 7-0)
	JP	GHXW			;GET HEX WORD INTO H,L
	JP	STORE			;STORE A BYTE TO MEMORY (CHECK)
	JP	NEGDE			;NEGATE D,E REGISTER
	jp	herr			;external hard disk boot error entry
	jp	boterr			;external boot error entry
	JP	INPORT			;INPUT FROM I/O PORT
	JP	OUTPORT			;OUTPUT TO I/O PORT
;
;
;
BEGIN::	

	IF	NOT TEST
	IF	SLAVE
	LD	A,11110001B		;ENABLE MEMORY HIGHEST SWITCHED BOUNDRY AND BANK 0
	OUT	(LSSP@),A		;WRITE TO MEMORY CONTROL PORT
	LD	A,00000001B		;MAKE SURE PROM IS ON
	OUT	(LCSP@),A		;WRITE TO SLAVE CONTROL PORT
;
	IN	A,(LCSP@)		;CHECK IF AUTO BOOT ENABLED
	AND	SENSW
	JP	Z,SLVBOOT		;IF SO GO DO IT
;
	ELSE
	LD	A,01001111B	;RESET POWER ON JUMP AND ENABLE MEMORY
	OUT	(16H),A		;WRITE TO CONTROL PORT
	ENDIF

	XOR	A			;CLEAR REG A
	LD	(FRSTIM),A		;SET FIRST TIME THRU BOOT FLAG
	LD	SP,STACK		;SET SP TO EXEC STACK AREA

; Set up SIO channels
	LD	HL,ISIOA		; point to SIO init table
	LD	BC,ISIOAL*256+SER0S	; length in B & port in C
	OTIR
	LD	HL,ISIOB		; repeat for channel B
	LD	BC,ISIOBL*256+SER1S
	OTIR
	ENDIF

	JP	SIGN			; go signon
; ****** INITIALIZATION TABLES FOR SIO DEVICES ******
;
; CHANNEL A
ISIOA::	DB	018H			; channel reset
	DB	004H			; write reg 4
	DB	044H			; X16 clock, 1 stop bit
	DB	003H			; write reg 3
	DB	0C1H			; Rx 8-bit char, Rx enable
	DB	005H			; write reg 5
	DB	0EAH			; DTR, Tx 8-bit char, Tx enable, RTS
;
;
	DB	000H			; read reg 0
ISIOAL	EQU	$-ISIOA			; length of sequence
;
; CHANNEL B
ISIOB::	DB	018H			; channel reset
	DB	004H			; write reg 4
	DB	044H			; X16 clock, 1 stop bit
	DB	003H			; write reg 3
	DB	0C1H			; Rx 8-bit char, Rx enable
	DB	005H			; write reg 5
	DB	0EAH			; DTR, Tx 8-bit char, Tx enable, RTS
;
	DB	000H			; read reg 0
ISIOBL	EQU	$-ISIOB			; length of sequence
;
SIGN::
	IF	SLAVE
	LD	A,B9600 * 16 + B9600	;SET BAUD RATE
	OUT	(BAUDRT),A
	ENDIF

	LD	HL,M0			;OUTPUT ENTRY SIGN-ON
	CALL	MSG			;PRINT IT
;
	LD	HL,M0A			;SEND MONITOR MESSAGE
	CALL	MSG
;
	IF	(NOT TEST) AND (NOT SLAVE)
	JP	BOOT			;TRY TO BOOT SYSTEM
	ENDIF
;
;	START OF MONITOR COMMAND AREA
;
NEXT::	LD	SP,STACK		;SET UP SP AGAIN
	LD	HL,M1			;OUTPUT PROMPTER (*)
	CALL	MSG			;PRINT IT
NEXT1::	CALL	CHIN			;GET COMMAND CHAR. IN

	IF	TEST
	CP	03			;CNTRL C
	JP	Z,0			;IF SO GO BACK TO CP/M
	ENDIF

	LD	B,A			;SAVE IT REG B
;
;	SEARCH TABLE FOR COMMAND
;
	LD	HL,OPTAB		;H,L POINTS TO START OF TABLE
SRCH::	LD	A,(HL)			;GET COMMAND BYTE
	CP	0FFH			;END OF TABLE?
	JR	Z,ILLEG			;NOT FOUND IN COMMAND
	CP	B			;DOES A = B?
	JR	Z,FNDCM			; YES!
	INC	HL			;BUMP 3 TIMES
	INC	HL			;FOR NEXT BYTE
	INC	HL
	JR	SRCH			;CONTINUE,,,
;
;	UNDEFINED COMMAND,,DO ERROR MESSAGE
;
ILLEG::	LD	HL,M2			;GET ERROR MSG
	CALL	MSG			;PRINT IT
	JR	NEXT			;TRY ANOTHER COMMAND
;
;	COMMAND FOUND,,GO DO IT
;
FNDCM::	INC	HL			;GET LOW ADDR. BYTE
	LD	E,(HL)			;PUT IT IN E REG
	INC	HL			;GET HIGH ADDR. BYTE
	LD	D,(HL)			;PUT IT IN D REG
	EX	DE,HL			;FLIP D,E & H,L
	JP	(HL)			;GO DO IT!
;
;
;	THIS IS AN OUTPUT ROUTINE FOR AN CRT
;
;
;
OUTPTY::
	PUSH	AF			;SAVE DATA
OUTPTC::
	IN	A,(SER0S)		;GET CRT STATUS
	AND	04H			;MASK BIT 7
	JR	Z,OUTPTC
	POP	AF			;GET DATA
	OUT	(SER0D),A
	RET	
;
;
;	THIS IS THE INPUT ROUTINE
;
;
;
INPUT0::
	IN	A,(SER0S)		;CHECK STATUS
	AND	01H			;MASK BIT 0
	RET	Z			;RET IF NO KEY PUSHED
	JR	INPUT1			;GET KEY PUSHED
;
;
INPUT::	IN	A,(SER0S)		;CHECK STATUS
	AND	01H			;MASK BIT 0
	JR	Z,INPUT			;NOT READY
INPUT1::
	IN	A,(SER0D)		;GET DATA
	AND	7FH			;GET RID OF HIGH ORDER BIT
	CP	'A' OR 20H
	RET	C			;RETURN IF LESS THAN LOWER CASE 'A'
	CP	'Z' OR 20H +1
	RET	NC			;RETURN IF GREATER THAN LOWER CASE 'Z'
	AND	5FH			;STRIP PARITY OFF AND LOWER CASE
	RET	
;
;
;	CHIN - INPUT ONE CHAR,,STRIP
;	PARITY,,ECHO IF >= SPACE
;
;
CHIN::	LD	A,0FFH			;SET ECHO
	LD	(ECHO),A		; FLAG ON
CHINN::	CALL	INPUT			;GET CHAR.
	PUSH	AF			;SAVE DATA
	LD	A,(ECHO)		; AND CHECK
	AND	A			;  ECHO FLAG
	JR	NZ,.CHINN1		;ECHO SET
	POP	AF			;ECHO NOT SET
	RET				; SO RETURN
.CHINN1::
	POP	AF			;RESTORE DATA & ECHO
	CP	20H			;CHECK FOR CNTL.
	CALL	NC,OUTPTY		;PRINT IF >= SPACE
	RET	
;
;
;	MESSAGE PRINT ROUTINE
;
;
MSG::	PUSH	AF			;SAVE DATA
	PUSH	HL			;SAVE H,L
MNXT::	LD	A,(HL)			;GET CHAR
	OR	A			;IS IT ZERO?
	JR	Z,MDONE			;YES,,RESTORE REGS.
	CALL	OUTPTY			;PRINT IT!
	INC	HL			;BUMP H,L BY 1
	JR	MNXT			;DO AGAIN
;
;
MDONE::	POP	HL			;RESTORE H,L
	POP	AF			;RESTORE A
	RET				;BACK TO CALLER
;
;
;	ROUTINE TO TYPE CR,LF,RUBOUT
;
;
CRET::	PUSH	HL			;SAVE H,L
	LD	HL,CRMSG		;CR,LF,RBO MSG
	CALL	MSG			;PRINT IT
	POP	HL			;RESTORE H,L
	RET	
;
;
;
HOLDDIS::
	CALL	INPUT0			;KEY PUSHED YET?
	CP	ESC			;ESCAPE?
	JP	Z,NEXT			;BACK TO MONITOR
	CP	08H			;ANY KEY PUSHED?
	RET	NC			;YES,,PRINT MORE
	JR	HOLDDIS			;NO,,SO HOLD SOME MORE
;
;
;
;
;	ROUTINE TO TYPE A SPACE
;
;
SPACE::	PUSH	AF			;SAVE A
	LD	A,20H			;SPACE CHAR
	JR	THXN1			;PRINT IT
;
;
;	TYPES REG A
;
;	ON OUTPUT DEVICE
;
;
THXB::	PUSH	AF			;SAVE A
	RRCA	
	RRCA	
	RRCA	
	RRCA	
	CALL	THXN			;PRINT HEX NIBBLE
	POP	AF			;RESTORE DATA
;
;
;	ROUTINE TYPES ONE ASCII CHAR. FROM
;	BITS 3-0 OF REG A IN HEX
;
;
THXN::	PUSH	PSW
	AND	0FH			;ISOLATE B 3-0
	ADD	A,90H
	DAA
	ADC	A,40H
	DAA
THXN1::	CALL	OUTPTY			;PRINT IT
	POP	PSW
	RET	
;
;
;	ROUTINE TYPES A WORD IN HEX FROM
;	REG H,L
;
;
THXW::	PUSH	AF			;SAVE A
	LD	A,H			;GET HIGH BYTE
	CALL	THXB			;PRINT IT
	LD	A,L			;GET LOW BYTE
	CALL	THXB			;PRINT IT
	POP	AF			;RESTORE DATA TO A
	RET	
;
;
;	ROUTINE GETS ONE HEX CHAR FROM INPUT
;
;
GHXN::	CALL	CHIN			;GET CHAR
	CP	','			;IS IT AN COMMA
	RET	Z			;RETURN OK
	CP	' '			;IS IT AN BLANK
	RET	Z			;OK TOO
	CP	'0'
	RET	C			;RET IF < ZERO
	CP	':'			;IS IT NUMERIC?
	JP	C,GHX1			;CHAR IS 0 TO 9
	CP	'A'			;IS IT A - F?
	RET	C			;CHAR : TO ' '
	CP	'G'			;IS IT > F?
	CCF				;FLIP CARRY SENSE
	RET	C			;IT IS > F!
	SUB	7			;ADJ FOR A - F
GHX1::	SUB	'0'			;MAKE BINARY
	RET	
;
;
;	ROUTINE GETS ONE HEX BYTE FROM INPUT
;
;
GHXB::	PUSH	BC			;SAVE B,C
	PUSH	DE			;SAVE D,E
	LD	C,0			;CLEAR C
	LD	E,0
.GHXB1::
	CALL	GHXN			;GET LEFT NIBBLE
	JR	NC,.GHXB5		;HEX, JUMP OUT!
	CP	CR			;END OF INPUT
	SCF
	JR	NZ,.GHXB3		;ERROR IF BAD DATA
	LD	A,E			;CHECK IF FIRST CHAR
	OR	A
	JR	NZ,.GHXB2		;RETURN INPUT DATA IF NOT
	SCF				;OTHERWISE RETURN CR AND CARRY SET
	LD	A,CR
	JR	.GHXB3
.GHXB5::
	CP	10H			;ANYTHING ELSE IS END
	JR	NC,.GHXB2
	INC	E
	LD	B,A			;SAVE NEW NIBBLE
	LD	A,C			;GET LAST DATA
	ADD	A,A	
	ADD	A,A	
	ADD	A,A	
	ADD	A,A	
	ADD	A,B			;ADD LEFT NIBBLE
	LD	C,A			;PUT BACK IN SAVE REG
	JP	.GHXB1			;GET MORE
.GHXB2::
	LD	A,C			;GET VALUE TO RETURN
.GHXB3::
	POP	DE			;RESTORE D,E
	POP	BC			;RESTORE B,C
	RET	
;
;
;	ROUTINE GETS HEX WORD FROM INPUT
;
;
GHXW::	PUSH	DE
	LD	HL,0			;CLEAR RETURNED VALUE TO ZERO
	SCF				;CLEAR CARRY FLAG
	CCF
	PUSH	PSW			;SAVE ACC. AND FLAGS
.GHXW1::
	CALL	GHXN			;GET HEX NIBBLE
	JR	NC,.GHXW2		;SKIP IF NOT ERROR
	CP	CR			;END CHAR
	JR	NZ,.GHXW5
	CALL	SPACE
	JR	.GHXW3
.GHXW5::
	POP	PSW			;OTHERWISE GET PSW BACK
	SCF				;AND SET ERROR FLAG
	POP	DE
	RET
.GHXW2::
	CP	10H			;END OF INPUT ?
	JR	NC,.GHXW3
	ADD	HL,HL			;SHIFT OVER PRESENT VALUE
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	LD	E,A			;ADD IN NEW INPUT
	LD	D,0
	ADD	HL,DE
	JR	.GHXW1			;GO GET MORE
.GHXW3::
	POP	PSW
	POP	DE
	RET
;
;
;	ROUTINE TO STORE A BYTE IN MEMORY
;	WITH CHECK.
;
;
STORE::	LD	(HL),A			;STORE BYTE
	CP	(HL)			;CHECK IT
	RET	Z			;RETURN IF OK
	PUSH	HL			;SAVE ADDRESS
	LD	HL,M4			;TYPE ERROR
	CALL	MSG			;PRINT IT
	POP	HL			;RESTORE ADDRESS
STOREA::
	CALL	THXW			;TYPE BAD ADDRESS
	JP	NEXT			;RETURN TO MONITOR
;
;
;	MEMORY EXAM/MODIFY ROUTINES
;
;
GETAD::	CALL	GHXW			;GET ADDR.
	JP	NC,GTA1			;JMP IF VALID
ILLCH::	LD	HL,M3			;ILLEGAL INPUT
	JP	ILLEG+3
GTA1::	LD	(ADR),HL		;SAVE ADDR.
LOCAT::	CALL	CRET			;GET CR,LF
	LD	HL,(ADR)		;GET ADDR.
	CALL	THXW			;PRINT IT
	CALL	SPACE
	LD	A,(HL)
	CALL	THXB			;PRINT MEMORY CONTENTS
	CALL	SPACE
	CALL	GHXB			;GET DATA OR COMMAND
	JP	C,NONHX			;NON-HEX INPUT
	CALL	STORE			;STORE VALUE IF VALID
NXLOC::	LD	HL,(ADR)
	INC	HL			;BUMP H,L 1
	JP	GTA1			;CONTINUE
NONHX::	CP	CR			;IS IT CR?
	JP	Z,NEXT			;YES,,SO EXIT
	CP	20H			;IS IT SPACE?
	JP	Z,NXLOC			;GET NEXT ADDR.
	CP	'-'			;BACK ONE POSITION?
	JP	NZ,ILLCH
LSTLC::	LD	HL,(ADR)		;GET ADDR.
	DEC	HL			;DECREASE -1
	JP	GTA1			;CONTINUE
;
;
;	ROUTINE NEGATES REG D,E
;
;
NEGDE::	PUSH	AF			;SAVE DATA
	LD	A,D
	CPL	
	LD	D,A
	LD	A,E
	CPL	
	LD	E,A
	INC	DE
	POP	AF
	RET	
;
;
;	DUMP MEMORY ROUTINE
;
;
DUMP::	CALL	PU3			;GET HEX ADDR.
	CALL	PU3			;ANOTHER
;
;  FROM ADDR IN H,L TO ADDR IN D,E
;
	CALL	NEGDE			;COMP.D,E FOR END CK.
DMRET::	CALL	CRET			;GET CR,LF
	CALL	THXW			;PRINT ADDR
	CALL	SPACE
DMNXT::	CALL	SPACE
	LD	A,(HL)			;GET DATA
	CALL	THXB			;PRINT IT
	CALL	LAST			;CHECK FOR END
	CALL	ESCAPE			;CHECK FOR ABORT
	CP	'S'-40H			;CNTL-S?
	CALL	Z,HOLDDIS		;YES,,STOP DISPLAY
	LD	A,L			;CHECK FOR MOD 16
	AND	15
	JP	Z,DMRET			;DO NEW LINE IF 16
	JP	DMNXT			;CONTINUE
;
;
;	DIRECT GO-TO ROUTINE
;
;
GOTO::	CALL	PU3			;GET ADDR.
	EX	DE,HL			;FLIP D,E & H,L
	JP	(HL)			;BE THERE
HELP::	
	LD	HL,HELPM
	CALL	MSG
	JP	NEXT
;
;
;	ROUTINE CHECK FOR END OF ADDR
;
;
LAST::	PUSH	HL			;SAVE MEM ADDR
	ADD	HL,DE			;ADD NEG END OF ADDR
	JP	C,NEXT			;END,,BACK TO MONITOR
	POP	HL
	INC	HL
	RET	
;
;
;	MOVE ROUTINE
;
;
MOVE::	CALL	PU3			;GET ADDR
	PUSH	DE
	CALL	PU3
	CALL	PU3
	EX	DE,HL
	EX	(SP),HL
	CALL	NEGDE
MOV1::	LD	A,(HL)
	EX	(SP),HL
	CALL	STORE
	INC	HL
	EX	(SP),HL
	CALL	LAST
	CALL	ESCAPE			;ABORT?
	JP	MOV1
;
;
;	FILL ROUTINE
;
;
FILL::	CALL	PU3
	CALL	PU3
	CALL	NEGDE
	CALL	GHXB
	JP	C,ILLCH
FILLF::	CALL	STORE
	CALL	LAST
	JP	FILLF
;
;
;	ROUTINE INPUTS ADDR INTO
;	H,L,,,THEN XCHG'S WITH D,E
;
;
PU3::	CALL	GHXW
	JP	C,ILLCH
	EX	DE,HL
	RET	
;
;
;
ESCAPE::
	CALL	INPUT0			;CHECK FOR KEY PUSHED
	or	A			;key pressed
	JP	NZ,NEXT
	RET	
;
;	INPUT FROM PORT ROUTINE
;
;
INPORT::
	CALL	GHXB			;GET PORT NUMBER
	JP	C,ILLCH			;BAD NUMBER
	LD	C,A			;MOVE PORT FOR INPUT
	IN	A,(C)			;GET VALUE
	CALL	CRET			;NEW LINE
	CALL	THXB			;PRINT BYTE
	JP	NEXT			;ALL DONE
;
;	OUTPUT TO PORT
;
;
OUTPORT::
	CALL	GHXB			;GET PORT NUMBER
	JP	C,ILLCH			;ERROR IF BAD
	LD	C,A			;SAVE PORT
	CALL	GHXB			;GET DATA
	JP	C,ILLCH			;ERROR IF BAD
	OUT	(C),A			;SEND IT
	JP	NEXT			;ALL DONE
;
;
;	SLAVE BOOT ROUTINE
;
	IF	SLAVE
SLVBOOT::
	LD	BC,SLVBLKL*256+LCSP@	;SET UP BLOCK TRANS
	LD	HL,SLVBLK
	OUTI				;SEND SERVICE REQUEST
	DEC	C			;CHANGE PORT
	OTIR				;SEND BLOCK MESSAGE
	LD	B,80H			;SET UP RECIEVE BLOCK
	LD	HL,1000H
	INIR				;GET BLOCK
	JP	1000H			;GO TO SLAVE LOADER
;
SLVBLK::
	DB	9			;REQUEST SERVICE W/ PROM ON
	DB	1,4CH,0,0FFH,0FFH
	DB	0FFH,0FFH,0FFH,0FFH,0FFH
;
SLVBLKL	EQU	$-SLVBLK		;SLAVE BLOCK LENGTH

	ELSE

;
;	DISK BOOT ROUTINE
;
BOOT::	call	escape			;want to get out
	CALL	FPYINIT			;Initialize floppy controller
	call	hdcinit			;initialize hard disk controller
bloop:	call	escape			;want to get out
	call	fpyrdy			;try floppy
	call	hdcrdy			;try hard disk
	jr	bloop			;if here go back and start over
;
; 
fpyinit:
	XOR	A			;CLEAR DOUBLE DENSITY COMMAND
	OUT	(WAIT),A
	LD	A,0BH			;restore drive to track 0
	OUT	(FDC),A
	NOP	
	IN	A,(WAIT)		;WAIT FOR IT TO GET TO 0
	ret				; and return from whence we came
;
fpyrdy::
	IN	A,(FDC)			;DRIVE READY YET
	RLA
	ret	C			;IF not READY LEAVE
;
RDY::	LD	HL,1000			;TIMER
RDY0::	IN	A,(FDC)			;MAKE SURE NO INDEX PULSE
	AND	2
	JR	Z,RDY05			;LEAVE IF GONE
	DEC	HL			;CHECK FOR TIME OUT
	LD	A,L
	OR	H
	JR	NZ,RDY0			;IF NOT GO BACK FOR MORE
	ret				;not ready so leave
;
RDY05::	LD	B,10			;SET TIME OUT COUNT
RDY1::	LD	HL,16000		;SET REV. COUNT
RDY2::	IN	A,(FDC)			;DO WE HAVE AN INDEX PULSE
	AND	2
	JR	NZ,LOAD			;IF SO LEAVE
	DEC	HL			;OTHER WISE CHECK REV COUNTER
	LD	A,L
	OR	H
	JR	NZ,RDY2			;GO BACK IF NOT ONE REV YET
	DJNZ	RDY1			;CHECKED ENOUGH REV'S YET
	ret				;not ready so leave
;
LOAD::	LD	A,0FFH			;CLEAR FIRST TIME THRU BOOT FLAG
	LD	(FRSTIM),A
	LD	B,1			;Hard disk error message
	call	msg
	in	A,(hdcerr)		;get error
	call	thxb			;print it
	jp	next			;start over

	ENDIF		;SLVBOOT
;
;		
;	MONITOR MESSAGES
;
;
M0::	DB	CR,LF,' > ADVANCED DIGITAL CORP.'

	IF	SLAVE
	DB	CR,LF,'   SUPER SLAVE Running'
	ELSE
	DB	CR,LF,'   SUPER QUAD Running'
	ENDIF

	DB	CR,LF,0
M0A::	DB	'   Monitor Version 3.2'
	DB	CR,LF,'   Febuary - 1983'
	DB	CR,LF,'   Press "H" for help'

	if	not slave
	db	CR,LF,'Attempting to boot.......'
	DB	CR,LF,'Press any key to abort boot.'
	endif

	DB	CR,LF,0
M1::	DB	CR,LF,' >',0
M2::	DB	' UNDEFINED',0
M3::	DB	' ????',0
M4::	DB	CR,CR,LF,'MEMORY WRITE ERROR AT ',0
M4A::	DB	'ERROR',0
M5::	DB	' PAUSE',0
M7A::	DB	'? ',0
M8::	DB	' ABORTED',0
READST::
	DB	'STARTING ADDRESS:',0
ENDADD::
	DB	'ENDING ADDRESS:',0

	IF	NOT SLAVE
BTERR::	DB	CR,LF,'FDC COLD BOOT ERROR CODE ',0
FRSTMS::
	DB	CR,LF,'INSERT DISK & PRESS B TO BOOT',0
herrmsg::
	db	cr,lf,'HDC1001 COLD BOOT ERROR CODE ',0
	ENDIF

CRMSG::	DB	CR,LF,0
HELPM::	DB	CR,LF,'MONITOR COMMANDS :'

	IF	NOT SLAVE
	db	CR,LF,'Load disk boot loader'
	ENDIF

	DB	CR,LF,'DSSSS,QQQQ      = Dump memory in hex from S to Q'
	DB	CR,LF,'FSSSS,QQQQ,BB   = Fill memory from S to Q with B'
	DB	CR,LF,'GAAAA           = Go to address A'
	DB	CR,LF,'IPP             = Input from port P'
	DB	CR,LF,'LAAAA           = Load memory starting at A'
	DB	CR,LF,'MSSSS,QQQQ,DDDD = Move starting at S to Q to Addr. D'
	DB	CR,LF,'OPP,DD          = Output data D to port P'
	DB	CR,LF,'ESC will terminate any command'
	DB	0
;
;	THIS IS THE COMMAND TABLE
;	FOR THE NEW SYSTEM MONITOR
;
;
OPTAB::	DB	'L'			;COMMAND
	DW	GETAD			; FOR ADDRESS
	DB	CR			;COMMAND
	DW	NEXT			;OVER AGAIN
	DB	'.'			;COMMAND
	DW	LOCAT			; CURRENT LOC.
	DB	'-'			;COMMAND
	DW	LSTLC			; LOC - 1
	DB	'D'			;COMMAND
	DW	DUMP			; DUMP
	DB	'I'			;COMMAND
	DW	INPORT			; INPUT PORT
	DB	'O'			;COMMAND
	DW	OUTPORT			; OUTPUT TO PORT
	DB	'F'			;COMMAND
	DW	FILL			; FILL
	DB	'G'			;COMMAND
	DW	GOTO			; GOTO
	DB	'M'			;COMMAND
	DW	MOVE			; MOVE
	DB	'H'			;COMMAND
	DW	HELP			; HELP

	IF	NOT SLAVE
	DB	'B'			;COMMAND 'B'
	DW	BOOT			; BOOT FLOPPY
	ENDIF

	DB	0FFH			;TERMINATOR
	END	

