


*****************************************************************
*								* 
*    MORROW 68K SYSTEM monitor REV 0.				* 
*								*
*    initial coding:  5/3/84 -bjg-				*
*      								* 
*****************************************************************

ioaddr	=	$ff0000			* compupro i/o address space


*  Compupro interfacer IV equates

sio	=	ioaddr+$10		* interfacer base address
siostat	=	sio+$1			* uart status
siodat  =	sio			* uart data 
select	=	sio+$7			* group select port
console =	7			* interface left port

*   mult i/o equates

base	=	ioaddr+$48		* standard base address
grpctl	=	base+$7			* select port
group0	=	$08
group1	=	$09			* serial port 1
group2	=	$0A			* serial port 2
group3	=	$0B			* serial port 3


dll	=	base			* divisor latch lsb
dlm	=	base+$1			* divisor latch msb
ier	=	base+$1			* interrupt enable register
lcr	=	base+$3			* line control register
mcr	=	base+$4			* modem control register
lsr	=	base+$5			* line status register 
rbr	=	base			* receive buffer register
thr	=	base			* trasnmitter holding register

dlab	=	$80			* divisor latch access bit
thre	=	$20			* transmitter hold reg empty status
dr	=	$1			* received data ready status

wls0	=	$1			* word length select bit 0
wls1	=	$2			* word length select bit 1 (for 8 bit word)
stb	=	$4			* stop bit count (2 stop bits)
imask	=	$00			* non interupt mode
loop	=	$10			* UART loop mode


*  miscellaneous equates

alf	=	$a			* ascii line feed
acr	=	$d			* ascii carriage return
asp	=	$20			* ascii space
acs	=	$1a			* ascii clear for ADM31
	Š

* 	PIC equates

init	=	$010		* bit high to initialize the PIC
icw1	=	base + 4	* PIC initialization control word 1
icw2	=	base + 5	* PIC initialization control word 2
icw3	=	base + 5	* PIC initialization control word 3
icw4	=	base + 5	* PIC initialization control word 4
ocw1	=	base + 5	* PIC interrupt mask register
ocw2	=	base + 4	* PIC EOI register
picmask =	$ff		* mask to turn all interrupts off
ltim	=	$8		* level triggered mode
adi4	=	$4		* call address intervals = 4
adi8	=	00		* call address intervals = 8
sngl	=	02		* sole system PIC
ic4	=	01		* icw4 access bit
lovect	=	0		* call vectors begin at 0
hivect	=	0		* call vectors begin at 0
normal	=	0		* Master/Reg. nest/unbuffered/no AEOI/8085				*  -normal setting of OCW4 for Morrow Software
eoi	=	$20		* non-specific EOI constant
ivalu	=	init OR ltim OR adi4 OR sngl OR ic4 OR lovect


 ****************************************************************
 *								*
 *	DJ-DMA Equates						*
 *								*
 ****************************************************************

djchan	=	$50		* initial channel address 	
djattn	=	ioaddr+$ef	* dj attention port 

 ****************************************************************
 *								*
 *  	     DMA Winchester Controller Equates			*
 *								*
 ****************************************************************
cyl	=	306		* number cylinders for Seagate ST-506
heads	=	  4		* number heads for Seagate ST-506
stpdly	=	 $1e		* 15 msec for Seagate ST-506
hdsetl	=	  0		* 20 msec for Seagate ST-506
secsiz	=	  7		* 1024 byte sectors for CPM
readat	=	  0		* DMA controller read sector opcode
write	=	  1		* DMA controller write sector opcode
rhead	=	  2		* DMA controller read header opcode
format	=	  3		* DMA controller format track opcode
const	=	  4		* load drive constants command
sense	=	  5		* return drive status command
noop	=	  6		* command used when seeking
dmarst	=	 $54		* DMA controller reset port
attn	=	 $55		* DMA controller Attention port
stepout	=	 $10		* Step direction to track 0
stepin	=	  0		* Step direction away from track 0
track0	=	  1		* track 0 status
wfault	=	  2		* write fault condition from drive
dready	=	  4		* drive ready status
sekcmp	=	  8		* seek complete status
hdspt	=	 17		* number of sectors per track
iopb	=	 $50		* pointer to the channel
chan	=	 $80		* actual channel
select	=	chan + 3	* select byte in channelŠdmaddr	=	chan + 4	* 24 bit dma address location
arg	=	chan + 7	* beginning of four arguments to commands
cmmd	=	chan + 11	* actual command location
statis	=	chan + 12	* controller return status location 
link	=	chan + 13	* link field address for next command
bootad	=	$100		* dma address for first sector from hddma
good	=	$ff		* good status result

	
 ********************************************************	
 *							*
 *  The following routines make up the debugging tool	*
 *  called MON68.  					*
 *							*
 ********************************************************


monitor:
	call	ucrlf

start:	ld	sp,stack
	LD	DE,START		* monitor begins here
	PUSH	DE
	CALL	CRLF
	LD	C,':'
	CALL	cout1
STAR0:	CALL	TI
	OR	A
	JR	Z,STAR0
	CP	'z'+1
	JP	NC,ERROR
	LD	C,002H
	CP	'D'
	JR	Z,disp
	cp	'd'
	jr	nz,fill

* 
* 	DISPLAY MEMORY XXXX TO XXXX
* 
* 
DISP:	CALL	EXLF
DI0:	CALL	CRLF
	CALL	LADR
	LD	B,010H
DI1:	CALL	BLK
	LD	A,(HL)
	CALL	LBYTE
	CALL	HILOX
	DJNZ	DI1
	JR	DI0
* 
* 
* 
* 	FILL MEMORY XXXX TO XXXX WITH XX
* 
* 
* 
FILL:	CP	'F'
	JR	z,fill0
	cp	'f'
	jr	nz,goto
fill0:	CALL	EXPR3
FI0:	LD	(HL),C
	CALL	HILO
	JR	NC,FI0
	POP	DEŠ	JR	START
* 
* 
* 	GOTO (EXECUTE) XXXX
* 
* 
GOTO:	CP	'G'
	JR	Z,goto0
	cp	'g'
	jr	nz,mtest
goto0:	CALL	EXPR1
	CALL	CRLF
	POP	HL
	JP	(HL)
* 
* 
* 	TEST MEMORY XXXX TO XXXX
* 
* 
MTEST:	CP	'T'
	JR	Z,t10
	cp	't'
	jr	nz,move
t10:	CALL	EXLF
T1:	LD	A,(HL)
	LD	B,A
	CPL
	LD	(HL),A
	XOR	(HL)
	JR	Z,T2
	PUSH	DE
	LD	E,A
	CALL	HLSP
	CALL	QI1
	CALL	CRLF
	POP	DE
T2:	LD	(HL),B
	CALL	HILOX
	JR	T1
* 
* 
* 	MOVE DATA FROM XXXX TO XXXX
* 
* 
MOVE:	CP	'M'
	JR	Z,mvo0
	cp	'm'
	jr	nz,subs
mvo0:	CALL	EXPR3
MV0:	LD	A,(HL)
	LD	(BC),A
	INC	BC
	CALL	HILOX
	JR	MV0
STORE:	LD	(IX+00H),AŠ	INC	IX
	DEC	E
	RET
* 
* 
* 	EXAMINE AND/OR REPLACE MEMORY DATA
* 
* 
SUBS:	CP	'S'
	JR	Z,suo0
	cp	's'
	jp	nz,hexn
suo0:	CALL	EXPR1
	CALL	QCHK
	JP	C,ERROR
	POP	HL
SU0:	LD	A,(HL)
	CALL	LBYTE
	LD	C,02DH
	CALL	COPCK
	RET	C
	JR	Z,SU1
	PUSH	HL
	LD	HL,0
	LD	C,001H
	CALL	EX1
	POP	DE
	POP	HL
	LD	(HL),E
	LD	A,B
	CP	00DH
	RET	Z
SU1:	INC	HL
	CALL	CRLF
	PUSH	HL
	CALL	LADR
	CALL	BLK
	POP	HL
	JR	SU0
* 
* 
EXLF:	CALL 	EXPR
	POP	DE
	POP	HL
* 	CR/LF OUTPUT
* 
* 
CRLF:	PUSH	HL
	PUSH	BC
	LD	C,0DH
	CALL	cout1
	LD	C,0AH
	CALL	cout1
	POP	BC
	POP	HLŠ	CALL	CSTS
	OR	A
	RET	Z
* 
* 	CHECK FOR CONTROL CHARACTER
* 
* 
CCHK:	CALL	con1
	AND	07FH
	CP	013H	* CONTROL-S
	JR	Z,CCHK
	CP	003H	* CONTROL-C
	RET	NZ
ERROR:	CALL	MEMSIZ
	LD	DE,ERROR
	PUSH	DE
	LD	C,'?'
	CALL	cout1
	JP	START
HLSP:	CALL	LADR
* 
* 	PRINT SPACE CHARACTER
* 
BLK:	LD	C,020H


* ********************************************************
* *							*
* *  Console I/O routines for the Wunderbus I/O.  These	*
* *  routines assume that the uart divisor latch has 	*
* *  previously set (either on power up or in routine 	*
* *  executed before a trap to this routine occurred.    *
* *  The character to output should be in the 'C' reg-	*
* *  ister, the character received is returned in the	*
* *  'A' register.  UCSTS returns with zero flag set	*
* *  when no character is waiting in the UART buffer,	*
* *  or with A = FF if a character is waiting.		*
* *							*
* ********************************************************	


cout1:	call	coninit
cout2:	in	a,(lsr)			* get uart status
	and	thre
	jr	z,cout2		* loop until tbe
	ld	a,c
	out	(thr),a			* output the data to uart
	ret

con1:	call	coninit
con2:	in	a,(lsr)			* get uart status
	and	dr
	jr	z,con2			* wait until receive data available
	in	a,(rbr)			* read the uart data register
	and	07fh			* strip parityŠ	ret

csts:	call	coninit		
	in	a,(lsr)			* read uart status
	and	dr
	ret	z			* return zero set if no character
	ld	a,0ff
	ret				* return a = ff if character waiting

coninit:
	ld	a,group1
	out   	(grpctl),a		* set up for UART 1
	ld	a,wls0+wls1+stb		
	out 	(lcr),a			* 8 bit word, 2 bit stop bits
	ret		



* 	CONVERT HEX TO ASCII

CONV:	AND	00f
	ADD	A,090H
	DAA
	ADC	A,040H
	DAA
	LD	C,A
	RET
* 
* 	GET PARAMETERS 1,2,OR 3
* 
EXPR3:	INC	C
	CALL	EXPR
	CALL	CRLF
	POP	BC
	POP	DE
	POP	HL
	RET
EXPR1:	LD	C,001H
EXPR:	LD	HL,0
EX0:	CALL	TI
EX1:	LD	B,A
	CALL	NIBBLE
	JR	C,EX2
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	OR	L
	LD	L,A
	JR	EX0
EX2:	EX	(SP),HL
	PUSH	HL
	LD	A,B
	CALL	QCHK
	JR	NC,EX3Š	DEC	C
	RET	Z
EX3:	JP	NZ,ERROR
	DEC	C
	JR	NZ,EXPR
	RET
HILOX:	CALL	HILO
	RET	NC
	POP	DE
	RET
HILO:	INC	HL
	LD	A,H
	OR	L
	SCF
	RET	Z
	LD	A,E
	SUB	L
	LD	A,D
	SBC	A,H
	RET
* 
* 	HEXADECIMAL ARITHMETIC
* 
HEXN:	CP	'H'
	JR	Z,hexd
	cp	'h'
	jr	nz,port
hexd:	CALL	EXLF
	PUSH	HL
	ADD	HL,DE
	CALL	HLSP
	POP	HL
	OR	A
	SBC	HL,DE
* 
* 	CONVERT HL REGISTER TO ASCII
* 
LADR:	LD	A,H
	CALL	LBYTE
	LD	A,L
* 
* 	CONVERT A REGISTER TO ASCII
* 
LBYTE:	PUSH	AF
	RRCA
	RRCA
	RRCA
	RRCA
	CALL	DBLC
	POP	AF
DBLC:	CALL	CONV
	JP	cout1			* checked

MEMSIZ:
	LD	HL,(STACK)Š	RET

NIBBLE:
	cp	'a'			* is it less than lower case 'a'?
	jr	c,nibok		* take jump if so
	cp	'z'+1			* less than a lower case 'z'?
	ccf				* set carry and return if > 'z'
	ret	c
	sub	' '			* convert to upper case
nibok:	SUB	030H
	RET	C
	cp	017h
	ccf
	RET	C
	CP	00AH
	CCF
	RET	NC
	SUB	007H
	CP	00AH
	RET
COPCK:	CALL	cout1
PCHK:	CALL	TI
* 
* 	CHARACTER CHECK
* 
QCHK:	CP	020H
	RET	Z
	CP	02CH
	RET	Z
	CP	00DH
	SCF
	RET	Z
	CCF
	RET
* 
* 	ECHO CONSOLE
* 
TI:	CALL	con1
	INC	A
	RET	Z
	DEC	A
	AND	07FH
	RET	Z
	CP	000H
	RET	Z
	CP	04EH
	RET	Z
	CP	06EH
	RET	Z
	PUSH	BC
	LD	C,A
	CALL	ucout1
	LD	A,C
	POP	BC
	RETŠ
* 
* 	READ/WRITE TO I/O PORT
* 
PORT:	CP	'O'
	JR	Z,QOUT
	CP 	'o'
	jr	z,qout
	CP	'I'
	JR	Z,in
	cp	'i'
	jr	z,in
	JR	VERIFY
IN:	CALL	EXPR1
	LD	C,0AH
	CALL	cout1
	POP	BC
Q0:	IN	E,(C)
QI1:	LD	B,008H
	CALL	BLK
QI2:	SLA	E
	LD	A,018H
	ADC	A,A
	LD	C,A
	CALL	cout1
	DJNZ	QI2
	RET
QOUT:	CALL	EXPR
	POP	DE
	POP	BC
	OUT	(C),E
	RET
* 
* 
* 
* 
* 	VERIFY MEMORY XXXX TO XXXX WITH XXXX
* 
VERIFY:
	CP	'V'
	JR	Z,ver0
	cp	'v'
	jr	nz,retrn
ver0:	call 	expr3
VERIO:	LD	A,(BC)
	CP	(HL)
	JR	Z,U..B
	PUSH	BC
	CALL	CERR
	POP	BC
U..B:	INC	BC
	CALL	HILOX
	JR	VERIO

Š
* 	Return to task which just trapped with old pc and registers restored

retrn:	cp	'C'
	jr	z,retr1
	cp	'c'	
	jr	nz,contr
retr1:	ld	a,(ctask)
	call	tskbase
	ld	de,mskofst
	add	hl,de
	ld	a,(hl)
	or	08
	ld	(hl),a
	jp	otask


* 	Return to trapped task, execute next instruction and trap back

contr:	cp	'U'
	jr	z,cont1
	cp	'u'
	jr	nz,boot
cont1:	ld	a,(ctask)
	call	tskbase
	ld	de,mskofst
	add	hl,de
	ld	a,(hl)
	and	0f6			* force mask for stop and run enble low
	ld	(hl),a
	jp	otask	

* 	Jump to the cpu switch address into task specified by CTASK

boot:	cp	'B'
	jr	z,boot1
	cp	'b'
	jp	nz,error
boot1:	ld	a,(ctask)
	call	tskbase
	push	hl
	ld	a,(switch)
	and	0f8
	cp	0			* check for a HDCA hard disk boot
	jp	z,boot2
	cp	08			* check for DMA hard disk boot
	jp	z,boot2
	cp	010			* check for DJ-DMA
	jp	z,boot2
	ld	de,pcofst
	add	hl,de
	ld	(hl),0
	inc	hl
	ld	(hl),a
boot2: ld	a,(cmask)Š	pop	hl
	ld	de,mskofst
	add	hl,de
	ld	(hl),a
	jp	oldtask



* 	MEMORY MISMATCH PRINTOUT
* 
CERR:	LD	B,A
	CALL	HLSP
	LD	A,(HL)
	CALL	LBYTE
	CALL	BLK
	LD	A,B
	CALL	LBYTE
	JP	CRLF


	.end
