.pabs
.phex
.xlink
.xsym
.title	"Z80 IceBox  version 1.0"
; **************************************
; **                                  **
; **  IIIIII    CCCCCC    EEEEEEEEEE  **
; **    II    CC      CC  EE          **
; **    II    CC          EE          **
; **    II    CC          EEEEEE      **
; **    II    CC          EE          **
; **    II    CC      CC  EE          **
; **  IIIIII    CCCCCC    EEEEEEEEEE  **
; **                                  **
; **************************************
; * EQUATES * 
; *********** 
	.PRNTX	"Z80 ICEBOX - HEAD OF ASSEMBLY"
REGSS	=\	"1=ASSEMBLE REGISTER MODIFY CODE,0=DROP"
MEMSS	=\	"1=ASSEMBLE MEMORY & PORT MODIFY,0=DROP"
R2708	=\	"1=2708 0=2716 VERSION"

ICERAM	==	0FC00H
ICEROM	==	0F000H
MESSAGES==	0D002H
MESS6	==	0D000H
CTRLC	==	'C'&1FH
CTRLX	==	'X'&1FH
CR	==	0DH
LF	==	0AH
ARROW	==	5EH
DEL	==	7FH
BS	==	8
DELCHAR	==	5FH
SPACE	==	20H
COMMA	==	02CH
SLASH	==	02FH
PERIOD	==	02EH
; INPUT-OUTPUT EQUATES
CRTD	==	0E0H
CRTS	==	CRTD+1
LPTD	==	0E2H
LPTS	==	LPTD+1
DATA	==	0E4H
SECTOR	==	DATA+1
TRACK	==	DATA+2
COMMAND	==	DATA+3
STATUS	==	COMMAND
SELECT	==	0F1H
FIFO	==	0F2H
CENABLE	==	0F0H
EXTL	==	0F8H
EXTH	==	0F9H
WPROTL	==	0FAH
WPROTH	==	0FBH
BADRH	==	0FCH
BADRL	==	0FDH
BTYPE	==	0FEH
MISC	==	0FFH
IOBYTE	==	3
	.PAGE
; *************
; * RAM CELLS *
; *************
	.LOC	ICERAM
	.BLKB	32
STACK	==	.
NMIJP:	.BLKW	1
DMA:	.BLKB	2	; DMA ADDRESS FOR DISC
TRK:	.BLKB	1	; TRACK NUMBER FOR DLAYED SEEK
IFF:	.BLKB	1	; INTRRUPT FLIP FLOP
EIDI:	.BLKB	1	; ENABLE OR DISABLE
JUMPER:	.BLKB	1	; FOR JUMP INSTRUCTION
PCSAVE:	.BLKW	1	; SAVE BUFFER FOR USER REGISTERS
SPSAVE:	.BLKW	1	; SAVE BUFFER FOR USER STACK
	.BLKW	4
IYSAVE:	.BLKW	1
IXSAVE:	.BLKW	1
	.BLKW	3
AFSAVE:	.BLKW	1
MONSP:	.BLKW	1	; MONITOR STACK POINTER SAVE
DMPLOW:	.BLKW	1	; LIMITS FOR DUMP
DMPHI:	.BLKW	1
DMPSTA:	.BLKB	1	;DUMP STATUS BYTE
BTSAVE:	.BLKB	1	; BREAK TYPE SAVE
KEYBUF:	.BLKB	80	; KEYBOARD I/O BUFFER
	.LOC	ICERAM+128
BUFFER:	.BLKB	128	; DISC SECTOR BUFFER
	.PAGE
; ******************
; * INITIALIZATION *
; ******************
	.LOC	ICEROM
	JMP	ICE	;GET PC TO F003
ICE:	LXI	SP,STACK
	XRA	A	; ZERO ALL THE MAPS
	MVI	B,5
	LXI	H,DMPLOW
..CLR:	MOV	M,A
	INX	H
	DJNZ	..CLR
	LXI	B,EXTL+800H	; AND TURN ON STUFF
..INIT:	OUTP	A
	INR	C
	JRNZ	..INIT
	; TURN ON THE MESSAGES
	INR	A
	OUT	CENABLE
	; INITIALIZE THE USARTS
	LXI	B,CRTS+0200H
	LXI	D,0AE40H	; INITIALIZATION DATA
	LXI	H,4E27H		; *16\8 BITS\NO PARITY\1STOP
..ILP1:	;INP	A
;	RRC
;	JRNC	..ILP1
..ILP2:	OUTP	D
	OUTP	E
	OUTP	H
	OUTP	L
	DCR	C	; ==CRTD
	INP	A	; FLUSH THE DATA
	INP	A
	MVI	C,LPTS
	DJNZ	..ILP1
	; INIT THE RAM
	LXI	H,STACK
	SHLD	MONSP	; SET UP REASONABLE MONITOR STACK
	MVI	A,1	; ICE SIGNON
	CALL    PRINTM
	JMP	MAINLOOP
	.PAGE
; *****************************************
; **
; **  CRTOUT - SEND A CHARACTER TO THE CRT
; **
; ** ENTRY -  A -> CHARACTER
; **
; ** EXIT  -  EVERYTHING RESTORED
; **
; *****************************************
PUNCH:
CONOUT:	MOV	A,C
CRTOUT:	PUSH    B
	MVI	C,CRTS
	JMPR	UART


; **************************************************
; **
; **  LPTOUT - SEND CHARACTER TO PRINTER, EAT CR'S
; **	WAIT FOR DATASET READY.
; **
; **  ENTRY -  A -> CHARACTER
; **
; **  EXIT  -  ALL RESTORED
; **
; **************************************************
LPTOUT:	CPI	0DH	; NO CARRIAGE RETURN
	RZ
	PUSH	B
	MVI	C,LPTS
..LPT:	INP	B
	BIT	7,B	; DATA SET READY
	JRZ	..LPT
UART:	INP	B
	BIT	0,B
	JRZ	UART
	DCR	C
	OUTP	A
	POP	B
	RET
	.PAGE
; *******************************************
; **
; **  NON MASKABLE INTERUPT  -  BREAKPOINT PROCESSING
; **
; *******************************************
	.LOC	ICEROM+66H	; NMI POINT
	JMP	NMI	; CHANGE TOP ADDRESS BITS TO REAL ADDR
NMI:	STA	AFSAVE
	IN	FIFO
	STA	PCSAVE+1
	IN	FIFO
	STA	PCSAVE
	IN	FIFO	; SHOULD BE A AGAIN
	INX	SP
	INX	SP
	LSPD	SPSAVE
	LXI	SP,AFSAVE+2	;PUSH EVERYTHING
	PUSH	PSW
	XRA	A
	OUT	BTYPE
	INR	A	; WRITE PROTECT
	OUT	MISC
	PUSH	B
	PUSH	D
	PUSH    H
	PUSH	X
	PUSH	Y
	EXAF
	PUSH	PSW
	EXX
	PUSH	B
	PUSH	D
	PUSH	H
;	LSPD	MONSP
	LXI	SP,STACK
	LDAI		; CHECK INTERUPTS
	MVI	A,0FFH	; ENABLED
	JPE	..NMI2
	XRA	A
..NMI2:	STA	IFF
	LXI	H,NMIJP
	PCHL
	.PAGE
LIST:	LDA	IOBYTE
	ANI	0C0H
	CPI	80H
	MOV	A,C
	JNZ	PUNCH
	JMP	LPTOUT
; ******************************************
; **
; **  PRINTM  -  PRINT MESSAGE FROM A POOL OF MESSAGES
; **
; **  ENTRY -  A -> NUMBER OF THE MESSAGE
; **
; **  EXIT  -  A -> ZORKED
; **		H -> ZORKED
; **
; ******************************************
PRINTM:	LXI	H,MESSAGES
	ORA	A
	JRZ	CONOMSG
	PUSH	B
	MOV	B,A
..LOOP:	MOV	A,M
	ANI	80H
	INX	H
	JRZ	..LOOP
	DJNZ	..LOOP
	POP	B
; ***********************************
; **
; **  CONOMSG  -  PRINT MESSAGE ON CONSOLE
; **
; **  ENTRY  -  HL -> STRING ENDD BY BYTE WITH SIGN BIT ON
; **
; **  EXIT  -   A -> ZORKED
; **H -> ZORKED
; **
; ***********************************
CONOMSG:MOV	A,M
	CALL	CRTOUT
	BIT	7,A	; TERMINATED BY BIT 7 ON
	RNZ
	INX	H
	JMPR	CONOMSG
	.PAGE
; *********************************
; **
; **  GETCHR - GET A CHARACTER FROM THE CRT AND
; **	FORCE TO UPPER CASE
; **
; **  EXIT -  A -> CHARACTER
; **
; *********************************
GETCHR:	CALL	CRTIN
	CPI	060H	;IS CHAR LOWER CASE???
	RM		;RETURN IF CHAR OK
	ANI	05FH	;FORCE IT TO UPPER CASE
	RET

CONIN:
READER:
CRTIN:	CALL	CRTSTAT
	JRZ	CRTIN
	IN	CRTD
	ANI	7FH
	CPI	5FH
	RNZ
	MVI	A,7FH
	RET


LPTIN:	CALL	LPTSTAT
	JRZ	LPTIN
	IN	LPTD
	RET


CONSTAT:
CRTSTAT:	PUSH	B
	MVI	C,CRTS
	JMPR	UARTSTAT


LPTSTAT:	PUSH	B
	MVI	C,LPTS
UARTSTAT:	INP	A
	POP	B
	ANI	2	; DATA READY?
	RZ	
	MVI	A,0FFH	; TRUE FOR CP\M
	RET

; ***************************
; **  INPUT ROUTINE FOR DEBUG
; ***************************
INCHAR:	CALL	GETCHR
	CPI	CTRLX
	RNZ	
	JMP	DEBUG
	.PAGE
; ***********************
; **
; **  UPPER LEVEL ICE
; **
; ***********************
ERROR:	MVI	A,0	; PRINT 'WHAT?'
	CALL	PRINTM
MAINLOOP:	; PROMPT USER
	MVI	A,2	; %
	CALL	PRINTM
	CALL	GETCHR
	CPI	CTRLC
	JRZ	BOOT	; ^C = BOOT CP\M
	CPI	CTRLX
	JRZ	MAINLOOP   ; ^X = KILL LINE
	CPI	'A'
	JRZ	ARCADESET  ; A = SET ARCADE MODE
	CPI	'C'
	JRZ	COMERCIAL   ; C = SET COMMERCIAL MODE
	CPI	'D'
	JZ	DEBUGE	; D = DEBUG MODE
	JMPR	ERROR



ARCADESET:		; SET MEMORY MAP\WRITE PROTECT
	MVI	A,24
	LXI	D,13H
	LXI	H,0FFFFH
	JMPR	PREBUG


COMERCIAL:
	MVI	A,25
	LXI	D,050F0H
	LXI	H,0FFFFH
;	JMPR	PREBUG


PREBUG:	; SET WRITE PROTECT AND EXTERNAL MAP
	MVI	C,EXTL
	OUTP	E
	INR	C
	OUTP	D
	INR	C
	OUTP	L
	INR	C
	OUTP	H
	CALL	PRINTM
	JMP	DEBUGE
	.PAGE
; ************************************
; **
; **  BOOT - PERFORMS CP\M BOOTSTRAP
; **	READS TRACK 0-SECTOR 1 THRU TRACK 1-SECTOR 20
; **	INTO MEMORY STARTING AT LOAD POINT DETERMINED
; **	BY LOCATION 2 OF TRACK 0-SECTOR 2 MINUS 3 TIMES 256
; **
; ************************************
WBOOT:	.BYTE	3EH
BOOT:	.BYTE	0AFH
	EXAF
	LXI	SP,STACK
	IM0		; 8080 MODE
	MVI	A,4
	OUT	SELECT
	MVI	A,5
	OUT	0EH
	CALL	HOME
	MVI	C,2
	CALL	SETSEC
	LXI	B,BUFFER
	CALL	SETDMA
	CALL	READ
	ORA	A
	JNZ	MAINLOOP
	LDA	BUFFER+2
	SBI	3
	LXI	H,2900H
	MVI	L,0
	MOV	H,A
	PUSH	H
	POP	X
; SUPER BOOT
	MVI	E,25	; NUMBER OF SCTORS
..LP2:	LXI	B,128*256+DATA
	MVI	A,#10011100B	; MULTIPLE READS
	OUT	COMMAND
..LP3:	EI
	HLT
	INI
	JNZ	..LP3
	DCR	E	; NUMBER OF SECTORS TO GO
	MVI	B,128
	JNZ	..LP3
; FORCE INTERUPT
	MVI	A,#11010000B	; IMMEDIATE
	OUT	COMMAND
..LP4:	CALL	DSTAT
	JRNZ	..LP4
	IN	TRACK
	CPI	#1
	JRZ	..LP5
	MVI	A,1
	STA	TRK
	CMA
	OUT	SECTOR
	PUSH	H
	CALL	SEEK
	POP	H
	ORA	A
	JNZ	MAINLOOP
	MVI	E,18	; MORE SECTORS
	JMPR	..LP2
..LP5:	PUSH	X
	POP	H
	LXI	B,1500H
..LP6:	MOV	A,M
	CMA
	MOV	M,A
	INX	H
	DCR	C
	JNZ	..LP6
	DJNZ	..LP6
; DONE READING IN CPM NOW FIX JUMPS IN MEMORY
; AND DO MISC STUFF
	PUSH	X
	POP	D
	LXI	H,WBOOT
	SHLD	1	; JMP ADDR
	MVI	A,0C3H
	STA	0
	STA	5
	LXI	H,806H
	DAD	D
	SHLD	6
	LXI	H,1500H
	DAD	D
	LXI	D,CPMJPS
	XCHG
	LXI	B,15*3
	LDIR
; COLD OR WARM
	EXAF
	ORA	A
	JRNZ	BDONE
; COLD
	LXI	H,0
	SHLD	3	; ZAP IOBYTE AND DISC
	MVI	A,3
	CALL	PRINTM
BDONE:	LDA	4
	ANI	1
	MOV	C,A
	PCIX
	.PAGE
; ********************
; **
; **  CP\M DISC ROUTINES
; **
; ********************
	; HOME DRIVE  -  NO INPUTS
HOME:	XRA	A
	STA	TRK
	MVI	D,3
	LXI	H,.
	MVI	A,#00001110B
	OUT	COMMAND
	JMP	SEEKWAIT


	; SETTRK - SET TRACK TO VALUE IN C REG
SETTRK:	MOV	A,C
	STA	TRK
	RET


	; SETSEC - SET SECTOR TO VALUE IN C REG
SETSEC:	MOV	A,C
	CMA
	OUT	SECTOR
	RET


	; SET DISC NUMBER TO VALUE IN C REGISTER (0-3)
SELDSK:	MOV	A,C
	SET	2,A
	OUT	SELECT
	RET

	; SET BUFFER ADDRESS TO VALUE IN BC REG PAIR
SETDMA:	SBCD	DMA
	RET

	; READ A SECTOR RETURN 0=NO ERRORS 1=ERROR
READ:	CALL	SEEK
	ORA	A
	RNZ	
	MVI	D,4
..READ1:	LHLD	DMA
	LXI	B,128*256+DATA
	MVI	A,#10001100B	; READ COMMAND
	OUT	COMMAND
..LOOP:	EI
	HLT
	INI
	JNZ	..LOOP
; FIX COMPLEMENTED DATA
	LHLD	DMA
	MVI	B,128
..FLP:	MOV	A,M
	CMA
	MOV	M,A
	INX	H
	DJNZ	..FLP
	IN	STATUS	; CHECK UP
	CMA
	ANI	9CH
	RZ	
	DCR	D
	JRNZ	..READ1
	JMP	WRER

	; WRITE A SECTOR. RETURN 0=NO ERRORS, 1=ERROR
WRITE:	CALL	SEEK
	ORA	A
	RNZ	
	LHLD	DMA
	LXI	D,BUFFER
	MVI	B,128
..WLP0:	MOV	A,M
	INX	H
	CMA
	STAX	D
	INX	D
	DJNZ	..WLP0
	MVI	D,3
..ELP:	LXI	H,BUFFER
	LXI	B,8000H+DATA
	MVI	A,#10101100B
	OUT	COMMAND
..OLP:	EI
	HLT
	OUTI
	JNZ	..OLP
	IN	STATUS	; CHECK OPERATION
	CMA
	ANI	0FCH
	RZ	
	DCR	D
	JRNZ	..ELP
WRER:	BIT	7,A
	JNZ	NOTRDY
	MVI	B,15	; WRITE PROTECTED
	BIT	6,A
	JRNZ	WERROR
	MVI	B,16	; WRITE FAULT
	BIT	5,A
	JRNZ	WERROR
	MVI	B,13	; RECORD NOT FOUND
	BIT	4,A
	JRNZ	WERROR
	MVI	B,12	; CRC ERROR
	BIT	3,A
	JRNZ	WERROR
	MVI	B,14	;LOST DATA
WERROR:	MOV	A,B
	CALL	PRINTM
	MVI	A,1
	RET


SEEK:	MVI	D,3	; NUMBER OF RETRYS
	LXI	H,..SK2
	IN	TRACK
	MVI	B,A
	LDA	TRK
	CMA
	CMP	B
	JRNZ	..SK2
	XRA	A
	RET
..SK2:	LDA	TRK
	CMA
	OUT	DATA
	MVI	A,#00011110B	; SEEK,HEAD LOAD, 10MS
	OUT	COMMAND

SEEKWAIT:	CALL DSTAT
	JRNZ	SEEKWAIT
	ANI	00011000B	; SEEK ERROR\CRC ERROR
	RZ	
	DCR	D
	JRZ	SEEKERROR
	PCHL		;RETRY

SEEKERROR:
	BIT	4,A
	MVI	B,11	; SEEK ERROR
	JRNZ	WERROR
	MVI	B,12	; CRC ERROR
	JMPR	WERROR


DSTAT:	IN	STATUS
	CMA
	BIT	7,A
	JRNZ	NOTRDY
	BIT	0,A
	RET


NOTRDY:	MVI	A,10	; NOT READY
	CALL	PRINTM
CPMJPS:	JMP	MAINLOOP

	JMP	WBOOT
	JMP	CONSTAT
	JMP	CONIN
	JMP	CONOUT
	JMP	LIST
	JMP	PUNCH
	JMP	READER
	JMP	HOME
	JMP	SELDSK
	JMP	SETTRK
	JMP	SETSEC
	JMP	SETDMA
	JMP	READ
	JMP	WRITE
	.PAGE
; ***********
; ** DEBUG **
; ***********
DEBUGE:	MVI	A,27
	CALL	PRINTM
	JMPR	DEBUG
DERROR:	MVI	A,0
	CALL	PRINTM
DEBUG:	LXI	SP,STACK
	LXI	H,DEBUG
	SHLD	NMIJP
	MVI	A,9
	CALL	PRINTM
..DB1:	CALL	INCHAR
	CPI	'B'
	JZ	BREAK
	CPI	'G'
	JZ	GO
	CPI	'D'
	JZ	DUMP
	CPI	'A'
	JZ	ASDUMP
	CPI	'Q'
	JZ	MAINLOOP
	CPI	'X'
	JZ	EXAMREGS
	.IFG	REGSS,[
	CPI	'R'
	JZ	REGISTER
]
	.IFG	MEMSS,[
	CPI	'M'
	JZ	MEMORY
	CPI	'P'
	JZ	PORT
]
	CPI	'S'
	JZ	STEP
	JMP	..DB1
	.PAGE
; ******************
; **
; **  BREAKPOINT
; **
; ******************
BREAK:	MVI	A,17		; 'BREAK ON '
	CALL	PRINTM
..BRK1:	CALL	INCHAR
	CPI	'M'
	LXI	B,200H+18
	JRZ	..BRK2
	CPI	'P'
	LXI	B,100H+19
	JRNZ	..BRK1
..BRK2:	MOV	A,C
	CALL	PRINTM
..BRK0:	CALL	INCHAR
	CPI	'R'
	JRNZ	..BK2
	SET	3,B
	MVI	A,20		; READ
	JMPR	..BK3
..BK2:	CPI	'W'
	JRNZ	..BRK0
	SET	2,B
	MVI	A,21
..BK3:	CALL	PRINTM
	MOV	A,B
	OUT	BTYPE
	STA	BTSAVE
	MVI	A,22		; ' AT '
	CALL	PRINTM
	CALL	KEYBD
	CALL	CONVRT
	MOV	A,C
	OUT	BADRL
	MOV	A,B
	OUT	BADRH
	JMP	DEBUG
	.PAGE
	.IFG	R2708,[.LOC	ICEROM+800H]
; **********
; **
; **  GO
; **
; **********
GO:	MVI	A,23
	CALL	PRINTM
	CALL	INCHAR
	CPI	0DH		; CR
	JRZ	..G2
	MVI	A,22		; AT
	CALL	PRINTM
	CALL	KEYBD
	CALL	CONVRT		; GET ADDRESS TO ..G TO
	MOV	H,B
	MOV	L,C
	SHLD	PCSAVE		;SAVE IN REGISTER AREA
..G2:	LDA	BTSAVE
	OUT	BTYPE
GO25:	XRA	A
	OUT	SELECT		; DISABLE FLOPPY INTERUPTS
	LXI	H,0C3F3H	; JP AND DI INSTRUCTIONS
	LDA	IFF	; INTERUPTS?
	ORA	A
	JRZ	..G3
	SET	3,L
..G3:	SHLD	EIDI	; LOADS JUMPER TOO
	SSPD	MONSP
	LXI	SP,PCSAVE+4
	POP	H
	POP	D
	POP	B
	EXX
	POP	PSW
	EXAF
	POP	Y
	POP	X
	POP	H
	POP	D
	POP	B
	POP	PSW
	LSPD	SPSAVE		; DON'T CHANGE FLAGS
	MVI	A,3		; TURN ON WRITE PROTECT
	OUT	MISC		; 4 M1'S TO ..G
	LDA	AFSAVE+1
	JMP	EIDI
	.PAGE
; ************
; **
; **  STEP
; **
; ************
STEP:	LXI	H,EXAMREGS
	SHLD	NMIJP
	LHLD	PCSAVE
	LXI	B,BADRH+0A00H
	OUTP	H
	INR	C
	OUTP	L
	INR	C
	OUTP	B	; SET BREAK TYPE
	JMP	GO25
	.PAGE
; **************
; **  MEMORY    **
; **	&	**
; **   PORT     **
; **************
	.IFG	MEMSS,[
MEMORY:	MVI	A,7		;"MEMORY "
	JMPR	P0
PORT:	LDA	DMPSTA	;GET STATUS BYTE
	SET	1,A		;SET PORT COMMAND BIT
	STA	DMPSTA
	MVI	A,29		;"PORT"
P0:	CALL	PRINTM
	CALL	KEYBD	;READ ADDRESS
	CALL	CONVRT	;MAKE IT BINARY
..P1:	LXI	H,KEYBUF
	MOV	D,B
	MOV	E,C
	CALL	DADDR	;PRINT ADDRESS ON TERMINAL
	LDA	DMPSTA
	BIT	1,A		;ARE WE IN PORT COMMAND????
	JRNZ	..M1
	MVI	A,5		; READ A EXT BYTE
	OUT	MISC
	LDAX	B	;READ FROM ..PORY LOCATION
	JMPR	..M2
..M1:	INP	A	;READ FROM USER TYPED PORT #
..M2:	CALL	ASCII
	LDA	DMPSTA	;CHECK IF ASCII BIT IS ON
	BIT	0,A		;PRINT BYTE IN ASCII??
	JRZ	..P1A
	BIT	1,A		;IF IN PORT COMMAND, NO ASCII
	JRNZ	..P1A
	MVI	M,SPACE
	INX	H
	MVI	M,SLASH
	INX	H
	MVI	A,5
	OUT	MISC	; TURN ON THE EXT SHIT
	LDAX	B	;GET DATA FROM MEMORY
	CALL	APRNT	;CHECK IF IT'S PRINTABLE
	MOV	M,A
	INX	H
	MVI	M,SLASH
	INX	H
..P1A:	MVI	M,SPACE+080H
	PUSH	B		;SAVE MEM LOCATION
	LXI	H,KEYBUF
	CALL	CONOMSG	;PRINT MEM & CONTENTS
	CALL	KEYBD	;READ ANY CHANGES
	LDAX	D
..P2:	CPI	COMMA
	JRZ	..P4
..P3:	CPI	CR		;DONE????
	JRNZ	..P5
..P4:	POP	B
	LDA	DMPSTA
	ANI	0FDH		;CLEAR OUT PORT BIT
	STA	DMPSTA
	JMP	DEBUG
..P5:	CPI	LF		;ADVANCE A LOCATION???
	JRNZ	..P6
	POP	B
	INX	B		;POINT AT NEXT LOC.
	JMPR	..P1
..P6:	CPI	ARROW	;GO BACKWARDS????
	JRNZ	..P7
	POP	B
	DCX	B		;DECREMENT PONITER
	JMPR	..P1
..P7:	CALL	CONVRT
	LDA	DMPSTA
	BIT	1,A		;IN PORT CO.MAND?????
	JRNZ	..M8
	MOV	A,C		;BINARY OF LAST TWO DIGITS TYPED
	POP	B		; GET BACK MEM LOCATION
	EXAF
	MVI	A,4
	OUT	MISC
	EXAF
	STAX	B	;PUT IN NEW DATA
	PUSH	B		;SAVE POINTER
	JMPR	..M9
..M8:	MOV	A,C		;GET DATA USER TYPED
	POP	B		;RESTORE PORT # IN 'C'
	OUTP	A	;WRITE DATA TO PORT
	PUSH	B
..M9:	LDAX	D	;GET TERMINATOR
	JMPR	..P2
]
	.PAGE
; ***************************
;***
;***  DUMP ROUTINE -
;***
;***  REGS  -  DE -> POINTS AT ..PORY
;***	HL -> OUTPUT BUFFER FOR 2-DIGIT HEX EQUIVALENTS
;***	BC ->   "	"	"  ASCII EQUIVALENT
;***
; ****************************
DUMP:	MVI	A,8		;"DUMP "
	CALL	PRINTM
	CALL	KEYBD	;READ UPPER & LOWER BOUNDS
	CALL	CONVRT
	LXI	X,DMPLOW	;TEMP STORAGE
	MOV	0(X),B
	MOV	1(X),C
	LDAX	D	; TEST FOR ONE INPUT
	CPI	COMMA
	JRZ	..0
	LXI	H,7FH
	DAD	B
	MOV	B,H
	MOV	A,L
	ORI	0FH
	MOV	C,A
	JMPR	..0A
..0:	INX	D		;BUMP OVER TERMINATOR
	CALL	CONVRT
..0A:	MOV	2(X),B	;SAVE UPPER BOUNDRY
	MOV	3(X),C
;
	MOV	A,0(X)	;CHECK FOR VALID BOUNDARIES
	CMP	B		;IS UPPER BOUND ACTUALLY HIGHER???
	JRZ	..1A
	JNC	DERROR
	JMPR	..1
..1A:	MOV	A,1(X)	;GET LOWER ADDR BITS
	CMP	C
	JNC	DERROR
..1:	MOV	D,0(X)
	MOV	A,1(X)
	ANI	0F0H		;START AT "XXX0" ADDR BOUNDRY
	MOV	E,A
..2:	CALL	DLOAD	;SET BUFFER POINTERS
	CALL	DADDR	;CONVRT "HL" TO ASCII
	MOV	A,E
;
..3:	CMP	1(X)	;ARE WE AT THE STARTING ADDRESS??
	JRZ	..4
	CALL	DFILL	;PUT IN BLANKS INSTED
	INX	D
	MOV	A,E
	JMPR	..3
;
..4:	MVI	A,5
	OUT	MISC
	LDAX	D	; GET CONTENTS OF EXT ..PORY
	PUSH	PSW
	CALL	ASCII	;CONVRT TO 2-DIGIT HEX
	MVI	M,SPACE
	INX	H
	POP	PSW		;GET AGAIN FOR ASCII VERSION
	CALL	APRNT	;IS CHAR PRINTABLE???
..6:	STAX	B	;PLACE IN ASCII CHAR
	INX	B
	MOV	A,D
	CMP	2(X)	;AT UPPER LIMIT???
	JRNZ	..7
	MOV	A,E
	CMP	3(X)	;ALL UPPER LIMIT BITS MATCH???
	JRZ	..9
..7:	MOV	A,E
	ANI	0FH		;MASK UPPER BITS
	CPI	0FH		;AT A LINE BOUNDARY???
	JRNZ	..8
	CALL	DPRNT
	CALL	DLOAD
	INX	D
	CALL	DADDR	;FILL IN ADDRESS
	JMPR	..4
..8:	INX	D	;BUMP TO NEXT LOCATION
	JMPR	..4
..9:	MOV	A,E	;DO WE HAVE TO FILL OUT THE LINE??
	ANI	0FH
	CPI	0FH	;AT THE END OF THE LINE
	JRZ	..10
	CALL	DFILL	;FILL IN WITH BLANKS
	INX	D
	JMPR	..9
..10:	CALL	DPRNT	;PRINT OUT LAST LINE
	JMP	DEBUG
;
;	EXTRA DUMPER ROUTINES
;
DFILL:	PUSH	B		;PUTS IN SPACES AS FILLER
	MVI	B,3
..DF1:	MVI	M,SPACE
	INX	H
	DJNZ	..DF1
	POP	B
	MVI	A,SPACE
	STAX	B
	INX	B
	RET
;
;
DADDR:	LDA	DMPSTA
	BIT	1,A		;IF IN PORT CMND, PRINT ONLY TWO DIGITS
	JRNZ	..D1
	MOV	A,D		;CONVERT "DE" TO ASCII
	CALL	ASCII
..D1:	MOV	A,E
	CALL	ASCII
	MVI	M,':'
	INX	H
	MVI	M,SPACE
	INX	H
	RET
;
;
DPRNT:	MVI	A,SLASH+080H	;PRINTS LINE ON TERMINAL
	STAX	B
	PUSH	D		;SAVE ..P LOC
	LXI	H,KEYBUF
	CALL	CONOMSG
	CALL	CRTSTAT	;ANYTHING TYPED???
	CPI	0FFH		;KEYBOARD INTERUPT???
	JRZ	..1
	LXI	H,MESS6
	CALL	CONOMSG
	POP	D
	RET
..1:	POP	H
	IN	CRTD	;READ TO RESET STATUS
	JMP	DEBUG

DLOAD:	LXI	H,KEYBUF	;RESET POINTERS
	LXI	B,KEYBUF+54
	MVI	A,SLASH
	STAX	B
	INX	B
	RET


APRNT:	CPI	07FH		;CHECK IF CHAR IS PRINTABLE
	JRNC	..AP1
	CPI	020H
	RNC
..AP1:	MVI	A,PERIOD
	RET
;
;
ASDUMP:	LDA	DMPSTA		;SET OR RESET BIT #1
	BIT	0,A		;IS IT ZERO??
	JRZ	..AD1
	RES	0,A		;CLEAR IT
	JMPR	..AD2
..AD1:	SET	0,A
..AD2:	STA	DMPSTA		;RESET THE BYTE
	JMP	DEBUG
	.PAGE
; ********************
; **
; **  REGISTER DUMP 
; **
; ********************
EXAMREGS:		;DUMP ALL THE REGISTERS
	MVI	A,26
	CALL	PRINTM
	LXI	D,KEYBUF
	LHLD	AFSAVE
	BIT	7,L
	CALL	PM
	BIT	6,L
	CALL	PM
	BIT	2,L
	CALL	PM
	BIT	0,L
	CALL	PM
	XCHG
	MOV	A,D
	CALL	DBYTE
	LXI	D,AFSAVE-1
	MVI	B,6
..DZ:	LDAX	D
	DCX	D
	CALL	DBYTE
	DJNZ	..DZ
	LDED	IXSAVE
	CALL	WORD
	LDED	IYSAVE
	CALL	WORD
	LDED	SPSAVE
	CALL	WORD
	LDED	PCSAVE
	CALL	WORD
	DCX	H
	SET	7,M
	LXI	H,KEYBUF
	CALL	CONOMSG
	JMP	DEBUG

PM:	MVI	A,'+'
	JRNZ	..SKIP
	MVI	A,SPACE
..SKIP:	STAX	D
	INX	D
	RET

DBYTE:	MVI	M,SPACE
	INX	H
	JMP	ASCII

WORD:	MVI	M,SPACE
	INX	H
	MOV	A,D
	CALL	ASCII
	MOV	A,E
	JMP	ASCII

	.PAGE
; **********************************************************
;***
;***	KEYBD - READ INPUT FOR CONSOLE TERMINAL
;***	SAVE & ECHO CHARACTERS 0-9, A-F & VALID
;***	TERMINATORS.	IGNORES ALL OTHER CHARACTERS
;***
;***	EXIT - DE -> POINTS AT INPUT STRING BUFFER
;***	A -> BLASTED
;***	B -> BLASTED
;***
; **********************************************************
KEYBD:	LXI	D,KEYBUF	;POINT AT STRING BUFFER
	MVI	B,0	;CLEAR CHARACTER COUNTER
..1:	CALL	GETCHR
	CPI	DELCHAR	; BACKSPACE ..???
	JRNZ	..2
	MOV	A,B	;ARE WE AT CHAR DELETE LIMIT???
	ORA	A
	JRZ	..1	;YUP....
	PUSH	D
	MVI	A,4	;<BS><SPACE><BS>
	CALL	PRINTM
	POP	D	;RESTORE POINTER
	DCX	D
	DCR	B	;CHECK CHAR COUNTER
	JMPR	..1
;
..2:	CPI	CR	;<CR>????
	JRZ	..3
	CPI	LF
	JRZ	..3
	CPI	ARROW
	JRNZ	..4
..3:	STAX	D	;SAVE CHARACTER
	MVI	A,6	;<CR><LF>
	CALL	PRINTM
	JMPR	..XIT
;
..4:	CPI	CTRLX	;SCRATCH THE WHOLE LINE
	JRNZ	..5
	JMP	DEBUG
;
..5:	CPI	COMMA	;ALLOW THESE THRU
	JRZ	..DIG
	CPI	''''
	JRZ	..DIG
	CPI	030H	;BELOW A ASCII "0"???
	JRC	..1
	CPI	'Z'	;HIGHER THAN AN "Z"???
	JRNC	..1
	CPI	03AH
	JRC	..DIG	;CHAR IS A "0-9"
	CPI	'A'
	JRNC	..DIG	;CHAR IS "A-Z"
	JMPR	..1
..DIG:	STAX	D	;SAVE THE CHARACTER TYPED
	INX	D	;BUMP TO NEXT CELL
	CALL	CRTOUT	;ECHO IT IN TERMINAL
	INR	B
	MOV	A,B
	CPI	24	;AT MAX # OF CHARACTERS
	JRNZ	..1	;GET MORE
	JMP	DERROR
..XIT:	LXI	D,KEYBUF
	RET
	.PAGE
; *****************************************************
;***
;***	CONVRT - CONVERT ASCII INPUT TO HEX BINARY
;***	LAST FOUR DIGITS BEFORE TERMINATOR
;***	ARE CONVERTED
;***
;***	ENTRY - DE -> POINTS AT ASCII INPUT STRING
;***
;***	EXIT	-	A -> BLASTED
;***	- BC -> BINARY EQUIV. OF LAST FOUR DIGITS
;***	- HL -> SAVED & RESTORED
;***	- DE -> UPDATED TO CONVERSION TERMINATOR
;***
; *****************************************************
CONVRT:	PUSH	H
	LXI	H,0	;CLEAR DATA REG PAIR
..1:	LDAX	D	;GET CHAR TO CONVERT
	CPI	CR	;CHECK FOR TERMINATOR
	JRZ	..OUT
	CPI	LF
	JRZ	..OUT
	CPI	ARROW
	JRZ	..OUT
	CPI	COMMA
	JRZ	..OUT
	CPI	03AH	;IS CHAR 0-9????
	JRC	..2
	CPI	'G'	;LEGAL CHARACTER???
	JRNC	..ERR
	SUI	7
..2:	SUI	030H
	MVI	B,4	;SHIFT AMOUNT
..3:	SLAR	L	;STUFF 0 INTO LOW BITS, HIGH INTO CARRY
	RALR	H	;CARRY ITTO LOW BIT, SCREW THE HIGH BIT
	DJNZ	..3
	ORA	L	;PLACE I	THE CURRENT CHAR
	MOV	L,A
	INX	D	;POINT AT NEXT CHAR
	JMPR	..1

..OUT:	MOV	B,H
	MOV	C,L
	POP	H
	RET

..ERR:	POP	H
	POP	H
	JMP	DERROR

	.PAGE
; ****************************************************
;***
;***	ASCII - CONVERT BINARY TO ASCII
;***
;***	ENTRY -	A -> DATA TO CONVERT
;***	- HL -> WHERE TO STUFF CONVERTED DATA
;***
;***	EXIT	-	A -> BLASTED
;***	- HL -> UPDATED TO NEXT AVAILABLE LOCATION
;***
; ****************************************************
ASCII:	PUSH	PSW
	ANI	0F0H	;MASK OUT LOW BITS
	CALL	..SFT
	CALL	..1	;MAKE ACCUM ..II
	MOV	M,A	;SAVE IT IN BUFFER
	INX	H	;BUMP POINTER
	POP	PSW	;NOW DO LOW 4 BITS
	ANI	0FH
	CALL	..1
	MOV	M,A
	INX	H
	RET

..1:	CPI	10
	JRC	..2
	ADI	7
..2:	ADI	030H
	RET

..SFT:	RAR
	RAR
	RAR
	RAR
	RET

	.IFG	REGSS,[
;**************************
;**	
;**	MODIFY REGISTERS
;**	
;**************************
REGISTER:
	MVI	A,28	;"MODIFY REGISTER"
	CALL	PRINTM
	CALL	KEYBD	;READ WHAT REG(S) ARE TO BE MODIFIED
	LXI	H,KEYBUF+30	;SKIP OVE INPUT SECTION
	LXI	X,PCSAVE	;POINT AT REG SAVE AREA
	LDAX	D
	MVI	M,SPACE
	INX	H
	CPI	'S'	;"SP"???
	JRNZ	..1
	LXI	B,2	;PUT IN OFSET TO REGISTER SAVE LOC.
	JMPR	..X
..1:	CPI	'P'	;"PC"???
	JRNZ	..2
	LXI	B,0
	JMPR	..X
..2:	CPI	'I'	;"IX OR IY"?????
	JRNZ	..3
	INX	D
	LDAX	D	;.. NEXT DIGIT
	CPI	'X'
	JRNZ	..2A
	LXI	B,14
	JMPR	..X
..2A:	CPI	'Y'
	JNZ	DERROR
	LXI	B,12
..X:	JMP	..D
;
..3:	LXI	B,15	;POINT TO SAVE AREA
	CPI	'L'	;WANT REG 'L' ??
	JRZ	..S
;
	INX	B
	INX	B
	CPI	'E'	;WANT 'E' REG???
	JRZ	..S
;
	INX	B
	INX	B
	CPI	'C'
	JRZ	..S
;
	INX	B
	INX	B
	CPI	'F'
	JRZ	..S
;
;
..7:	LXI	B,16	;POINT TO SAVE AREA
     	CPI	'H'
	JRNZ	..8
	INX	D
	LDAX	D	;GET NEXT CHAR
	CPI	'L'
	JMPR	..Q
..8:	INX	B
	INX	B
    	CPI	'D'
	JRNZ	..9
	INX	D
	LDAX	D	;GET NEXT CHAR
	CPI	'E'
	JMPR	..Q
..9:	INX	B
	INX	B
    	CPI	'B'
	JRNZ	..10
	INX	D
	LDAX	D	;GET NEXT CHAR
	CPI	'C'
	JMPR	..Q
..10:	CPI	'A'	;DUMP ACCUMULATOR
	JNZ	DERROR
..10A:	INX	B
	INX	B
	JMPR	..S
;
;
;	DUMP SINGLE REGISTER
;
..Q:	JRNC	..D	;DUMP DOUBLE REG
..S:	DADX	B	;POINT 'IX' AT REGISTER IN SAVE SPACE
	MOV	A,1(X)	;READ USER REGISTER CONTENTS
	CALL	ASCII
	CALL	RPRNT
	MOV	1(X),C	;CHANGE TO NEW CONTENTS
	JMP	DEBUG
;
..D:	DADX	B
	MOV	A,1(X)
	CALL	ASCII
	MOV	A,0(X)
	CALL	ASCII
	CALL	RPRNT
	MOV	1(X),B	;CHANGE TO NEW DATA
	MOV	0(X),C
	JMP	DEBUG
RPRNT:	MVI	M,SPACE+80H
	LXI	H,KEYBUF+30
	CALL	CONOMSG
	CALL	KEYBD
	LDAX	D
	CPI	CR
	JRZ	..1
	CALL	CONVRT
	RET
..1:	POP	B
	JMP	DEBUG
;
	]

	.END
