.Z80

; Michael Bleistein	Stefan Wimmer		Revision 1.2
; 3550 Marburg		12101 Berlin		Date: 23.05.88
;


;
; Konstanten
; ----------
;

BS	EQU	08H
HT	EQU	09H
LF	EQU	0AH
CR	EQU	0DH
ESC	EQU	1BH
DEL	EQU	7FH

_4MHz	equ	0	; 0 = Option inaktiv, 1 = aktiv
_6MHz	equ	1
;
; Ports etc.
; ----------
;

CTC0	equ	10h
CTC1	equ	11h
CTC2	equ	12h
CTC3	equ	13h

PIOad	equ	1Ch
PIOac	equ	1Dh
PIObd	equ	1Eh
PIObc	equ	1Fh

SIOad	equ	18h
SIOac	equ	19h
SIObd	equ	1Ah
SIObc	equ	1Bh

WDTc	equ	0F0h
WDTtc	equ	0F1h

DAISYch	equ	0F4h

RAMUSE	EQU	08000H		; ab hier kann RAM benutzt werden



	ORG	0000H




;
; Initialisierung
; ---------------
;


	LD	SP,STACK
	ld	a,10		; 4800 Bd
	ld	(PAR01),a
	call	BAUD

	;
	; Systempromter
	;

	CALL	PSTR
	DB	'TMPZ-MON V1.0',CR,LF,0

;
; Monitor Zeileninterpreter
; -------------------------
;

KOVW:	CALL	PSTR
	db	CR,LF,'>',0
	LD	HL,BUFF
	LD	B,0
KO03:	CALL	CONIN
	CP	BS
	JR	Z,KO01
	CP	DEL
	JR	Z,KO01
	CP	HT
	JR	Z,KO02
	LD	(HL),A
	CP	CR
	JR	Z,KO00
KO02:	INC	HL
	INC	B
KO12:	CALL	CONOUT
	LD	A,40
	CP	B
	JR	Z,KO00
	JR	KO03

KO01:	LD	A,B
	OR	A
	JR	Z,KO03
	DEC	HL
	DEC	B
	LD	A,BS
	JR	KO12

KO00:	CALL	CRLF
	LD	IX,PAR01
	LD	DE,BUFF
	LD	A,(DE)
	CP	CR
	JR	Z,KOVW
	LD	C,0
	LD	A,(BUFF+1)
	CP	CR
	JR	Z,KO04
KO07:	LD	HL,0
KO06:	INC	DE
	LD	A,(DE)
	CP	CR
	JR	Z,KO05
	CP	' '
	JR	Z,KO05
	CP	','
	JR	Z,KO05
	CALL	ASBI
	JR	C,KO08
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	A,L
	LD	L,A
	JR	KO06

KO05:	LD	(IX+0),L
	INC	IX
	LD	(IX+0),H
	INC	IX
	INC	C
	CP	CR
	JR	NZ,KO07

KO04:	LD	A,(BUFF)
	AND	5FH
	LD	B,A
	LD	HL,KOTBL
KO10:	LD	A,(HL)
	OR	A
	JR	Z,KO08
	CP	B
	INC	HL
	JR	Z,KO09
KO11:	INC	HL
	INC	HL
	INC	HL
	JR	KO10

KO09:	LD	A,(HL)
	CP	C
	JR	NZ,KO11
	INC	HL
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	EX	DE,HL
	CALL	HLI
	JP	KOVW

KO08:	LD	A,'?'
	CALL	CONOUT
	JP	KOVW

HLI:	JP	(HL)


;
; Kommandotabelle
; ---------------
;

KOTBL:	db	'G',1
	dw	GO
	db	'F',3
	dw	FILL
	db	'E',1
	dw	EXAM
	db	'M',3
	dw	MOVE
	db	'I',0
	dw	IN0
	db	'I',1
	dw	IN
	db	'O',1
	dw	OUT0
	db	'O',2
	dw	OUT
	db	'D',1
	dw	DUMP1
	db	'D',2
	dw	DUMP2
	db	'B',1
	dw	BAUD
	db	0

;==================================================================

;
; Monitorkommando BAUD
; --------------------
;
; Aufruf: bxx
;
; xx = Baudrate wie folgt:
;
;	0 =	   75 Baud
;	1 =	  110 Baud
;	2 =	  134 Baud
;	3 =	  150 Baud
;	4 =	  300 Baud
;	5 =	  600 Baud
;	6 =	 1200 Baud
;	7 =	 1800 Baud
;	8 =	 2400 Baud
;	9 =	 3600 Baud
;	10=	 4800 Baud
;	11=	 7200 Baud
;	12=	 9600 Baud
;	13=	19200 Baud

BAUD:
	ld	a,(PAR01)
	cp	14
	jp	c,Baud0
	pop	hl
	jp	KO08

Baud0:	call	getbd1		; TC lesen ( nach  )
	ld	c,CTC3		; CTC 3
	ld	b,01000101b	; Counter-Mode, TC folgt, no INT, cont.
	out	(c),b		; Befehl..
	out	(c),a		; ..und TC

	; ..jetzt SIO-Init

	ld	hl,i$SIO
	ld	bc,i$len*256+SIObc
	otir

	ld	a,(PAR01)
	cp	7
	jr	nc,Baud1
	ld	a,01001100b	; RxTxC x16, 2 Stopbits, no parity
	db	11h
Baud1:	ld	a,00001100b	; RxTxC x1, 2 Stopbits, no parity
	out	(SIObc),a
	RET

getbd1:
	ld	d,0
	ld	e,a
	ld	hl,Baud$Tab	; Zeiger auf Umrechnungstabelle
	add	hl,de
	ld	a,(hl)
	ret

;
; Tabellen
; --------
;

; 1. Initialisierung der SIO:

i$SIO:	db	00011000b	; reset
	db	00010011b	; reg 3:
	db	11000001b	; 8 bit, no auto, Rx enable
	db	00010101b	; reg 5:
	db	11101010b	; DTR=0, 8 bit, Tx enable, RTS=0
	db	00010100b	; reg 4:
i$len	equ	$-i$SIO


; 2. Tabelle der Teilerraten fuer den CTC:
 IF _4MHz
Baud$Tab:	; fuer 4 MHz
	db	  0	;   75 Baud
	db	175	;  110 Baud
	db	143	;  134 Baud
	db	128	;  150 Baud
	db	 64	;  300 Baud
	db	 32	;  600 Baud
	db	 16	; 1200 Baud
	db	171	; 1800 Baud
	db	128	; 2400 Baud
        db	 85	; 3600 Baud
        db	 64	; 4800 Baud
	db	 43	; 7200 Baud
        db	 32	; 9600 Baud
        db	 16	;19200 Baud
 ENDIF


 IF _6MHz
Baud$Tab:	; fuer 6 MHz
	db	  0	;   75 Baud	geht nicht!!!
	db	  0	;  110 Baud	geht nicht!!!
	db	215	;  134 Baud
	db	192	;  150 Baud
	db	 96	;  300 Baud
	db	 48	;  600 Baud
	db	 24	; 1200 Baud
	db	  0	; 1800 Baud
	db	192	; 2400 Baud
        db	128	; 3600 Baud
        db	 96	; 4800 Baud
	db	 64	; 7200 Baud
        db	 48	; 9600 Baud
        db	 24	;19200 Baud
 ENDIF

;
; Monitorkommando FILL
; --------------------
;
; Aufruf: fxxxxx,yyyy,zz
;
; xxxx = Startadresse
; yyyy = Endadresse
;   zz = Wert
;

FILL:	LD	HL,(PAR02)
	LD	DE,(PAR01)
	SBC	HL,DE
	RET	C
	INC	HL
	EX	DE,HL
FI00:	LD	A,(PAR03)
	LD	(HL),A
	INC	HL
	DEC	DE
	LD	A,D
	OR	E
	JR	NZ,FI00
	RET


;
; Monitorkommando EXAM
; --------------------
;
; Aufruf: exxxxx
;
; xxxx = Startadresse
;

EXAM:	LD	HL,(PAR01)
EX01:	LD	A,L
	AND	0FH
	LD	C,A
	LD	A,L
	AND	0F0H
	LD	L,A
	CALL	PADR
	LD	D,H
	LD	E,L
EX00:	CALL	SPACE
	LD	A,(DE)
	LD	B,A
	CALL	PDAT
	INC	DE
	LD	A,E
	AND	0FH
	JR	NZ,EX00
	CALL	PSTR
	db	CR,LF,20H,20H,20H,0
	INC	C
	DEC	HL
EX08:	CALL	PSTR
	db	20H,20H,20H,0
	INC	HL
	DEC	C
	JR	NZ,EX08
EX02:	CALL	CONIN
	CP	20H
	JR	Z,EX03
	CP	CR
	RET	Z
	CP	BS
	JR	Z,EX04
	CP	DEL
	JR	Z,EX04
	LD	C,A
	CALL	ASBI
	JR	C,EX02
	RLCA
	RLCA
	RLCA
	RLCA
	LD	B,A
	LD	A,C
	CALL	CONOUT
EX06:	CALL	CONIN
	CP	BS
	CALL	Z,CONOUT
	JR	Z,EX02
	LD	C,A
	CALL	ASBI
	JR	C,EX06
	ADD	A,B
	LD	B,A
	LD	A,C
	CALL	CONOUT
	LD	A,B
	LD	(HL),A
	CALL	SPACE
EX07:	INC	HL
	LD	A,0FH
	AND	L
	JR	NZ,EX02
EX09:	CALL	CRLF
	JP	EX01

EX03:	CALL	PSTR
	db	'   ',0
	JR	EX07

EX04:	LD	A,L
	DEC	HL
	AND	0FH
	JR	Z,EX09
	CALL	PSTR
	db	BS,BS,BS,0
	JR	EX02

;
; Monitorkommando MOVE
; --------------------
;
; Aufruf: mxxxxx,yyyy,zzzz
;
; xxxx = Startadresse
; yyyy = Endadresse
; zzzz = Zieladresse
;

MOVE:	LD	HL,(PAR02)
	LD	DE,(PAR01)
	SBC	HL,DE
	RET	C
	LD	B,H
	LD	C,L
	INC	BC
	EX	DE,HL
	LD	DE,(PAR03)
	PUSH	HL
	SBC	HL,DE
	POP	HL
	JR	NC,LDIR
	ADD	HL,BC
	EX	DE,HL
	ADD	HL,BC
	DEC	HL
	DEC	DE
MOV00:	CALL	MOV02
	DEC	HL
	DEC	DE
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,MOV00
	RET

LDIR:	EX	DE,HL
MOV01:	CALL	MOV02
	INC	HL
	INC	DE
	DEC	BC
	LD	A,B
	OR	C
	JR	NZ,MOV01
	RET

MOV02:	LD	A,(DE)
	LD	(HL),A
	RET

;
; Monitorkommando IN
; ------------------
;
; Aufruf: i
;
; Portadresse wird aus @IPort genommen
;

IN0:	ld	a,(@IPort)
	ld	(PAR01),a
	; weiter mit 'IN'...

;
; Monitorkommando IN
; ------------------
;
; Aufruf: ixx
;
; xx = Portadresse
;

IN:	LD	A,'('
	CALL	CONOUT
	LD	A,(PAR01)
	ld	(@IPort),a
	LD	C,A
	LD	B,A
	CALL	PDAT
	CALL	PSTR
	db	') = ',0
	IN	B,(C)
	JP	PDAT

;
; Monitorkommando GO
; ------------------
;
; Aufruf: gxxxxx
;
; xxxx = Startadresse
;

GO:	LD	HL,(PAR01)
	CALL	HLI
	RET

;
; Monitorkommando OUT
; -------------------
;
; Aufruf: oxx
;
; xx = Wert
;

OUT0:	LD	A,(PAR01)
	LD	(PAR02),A
	LD	A,(@OPort)
	LD	(PAR01),A
	; ..weiter wie gehabt...

;
; Monitorkommando OUT
; -------------------
;
; Aufruf: oxx,yy
;
; xx = Portadresse
; yy = Wert
;

OUT:	LD	A,(PAR01)
	LD	C,A
	ld	(@OPort),a
	LD	A,(PAR02)
	OUT	(C),A
	RET

;
; Monitorkommando DUMP
; --------------------
;
; Aufruf: dxxxxx
;	  dxxxxx,yyyy
;
; xxxx = Startadresse
; yyyy = Endadresse
;

DUMP1:	LD	HL,(PAR01)
	LD	(PAR02),HL
DUMP2:	LD	DE,(PAR01)
NXTADR:	LD	HL,(PAR02)
	XOR	A
	SBC	HL,DE
	RET	C
	LD	H,D
	LD	L,E
	CALL	PADR
NXTZEI:	CALL	SPACE
	LD	A,(DE)
	LD	B,A
	CALL	PDAT
	INC	DE
	LD	A,E
	AND	0FH
	JR	NZ,NXTZEI
	LD	D,H
	LD	E,L
	CALL	SPACE
NXTASC:	LD	A,(DE)
	CP	20H
	JR	C,NOASC
	CP	80H
	JR	NC,NOASC
	JR	DLOOP
NOASC:	LD	A,'.'
DLOOP:	CALL	CONOUT
	INC	DE
	LD	A,E
	AND	0FH
	JR	NZ,NXTASC
	CALL	CRLF
	LD	A,D
	OR	E
	RET	Z
	CALL	COSTAT
	OR	A
	JR	Z,NXTADR
	CALL	CONIN
	CP	CR
	RET	Z
	CALL	CONIN
	CP	CR
	RET	Z
	JR	NXTADR


;
; Unterprogramm CONOUT
; --------------------
;

CONOUT:	OUT	(SIObd),A
CONO00:	IN	A,(SIObc)
	BIT	2,A
	JR	Z,CONO00
	RET

;
; Unterprogramm COSTAT
; --------------------
;
;  = 0FFh wenn Zeichen da, sonst  = 00
;

COSTAT:	IN	A,(SIObc)
	BIT	0,A
	LD	A,0
	RET	Z
	DEC	A
	RET

;
; Unterprogramm CONIN
; -------------------
;

CONIN:	IN	A,(SIObc)
	BIT	0,A
	JR	Z,CONIN
	IN	A,(SIObd)
	RET

;
; Unterprogramm ASBI
; ------------------
;
; ASCII --> binaer
;

ASBI:	CP	'0'	
	RET	C
	CP	':'
	JR	C,AS00
	AND	5FH
	CP	'A'
	RET	C
	CP	'G'
	CCF
	RET	C
	SUB	7
AS00:	SUB	'0'
	RET

;
; Unterprogramm PHEX
; ------------------
;
; Lo-Nibble von A als Hexziffer ausgeben
;

PHEX:	AND	0FH
	CP	10
	JR	C,PH00
	ADD	A,7
PH00:	ADD	A,30H
	JP	CONOUT

;
; Unterprogramm PDAT
; ------------------
;
; Inhalt von B in Hexziffern ausgeben
;

PDAT:	PUSH	AF
	LD	A,B
	RRCA
	RRCA
	RRCA
	RRCA
	CALL	PHEX
	LD	A,B
	CALL	PHEX
	POP	AF
	RET

;
; Unterprogramm PADR
; ------------------
;
; Inhalt von HL in Hexziffern ausgeben
;

PADR:	PUSH	BC
	LD	B,H
	CALL	PDAT
	LD	B,L
	CALL	PDAT
	POP	BC
	JP	SPACE

;
; Unterprogramm PSTR
; ------------------
;
; String der dem Aufruf folgt bis zur 
;    Endemarkierung (00) ausgeben
;

PSTR:	EX	(SP),HL
	PUSH	AF
PS00:	LD	A,(HL)
	INC	HL
	OR	A
	JR	Z,PS01
	CALL	CONOUT
	JR	PS00
PS01:	POP	AF
	EX	(SP),HL
	RET

;
; Unterprogramm CRLF
; ------------------
;
; Die Sequenz CR LF ausgeben
;

CRLF:	CALL	PSTR
	db	CR,LF,0
	RET

;
; Unterprogramm SPACE
; -------------------
;
; Ein SPACE ausgeben
;

SPACE:	LD	A,' '
	JP	CONOUT

;======================================
;
; Datenbereiche
; -------------
;

BUFF	EQU	RAMUSE+1
PAR01	EQU	BUFF+40
PAR02	EQU	PAR01+2
PAR03	EQU	PAR02+2

@IPort	equ	PAR03+2
@OPort	equ	@IPort+1

STACK	EQU	RAMUSE+128

;
; Programmende
; ------------
;

	END

    Source: geocities.com/capecanaveral/6368

               ( geocities.com/capecanaveral)