1;
2;	OCR'ed by Larry Kraemer
3;	Corrected typos and modified for z80asm by Udo Munk
4;	January 2016
5;
6;	Use z80asm 1.8, won't assemble correct with versions before
7;
8STAT	EQU	0			;STATUS PORT, DEVICE A
9DATA	EQU	1			;DATA PORT, DEVICE A
10ACMNDP	EQU	2			;COMMAND PORT, DEV. A
11ABAUDP	EQU	0			;BAUD PORT, DEVICE A
12APARLP	EQU	4			;PARALLEL PORT, DEV. A
13BCMNDP	EQU	52H			;COMMAND PORT, DEV. B
14BPARLP	EQU	54H			;PARALLEL PORT, DEV. B
15DAV	EQU	40H			;DATA-AVLAILABLE MASK
16TBE	EQU	80H			;XMITTER-BUF-EMPTY MASK
17;
18NBRKPT	EQU	5			;ALLOW ROOM FOR
19BPSTOR	EQU	NBRKPT*4+2		;BREAKPOINT STORAGE
20TEMPS	EQU	BPSTOR
21BPMRK	EQU	0BH			;USED TO MARK THE SET-
22;					;TING OF A BP IN BPSTOR.
23RSTLC	EQU	30H			;RST LOCATION
24CASE	EQU	0			;(REQUIRES UPPER-CASE)
25B2F	EQU	5			;2-BYTE FLAG
26PF	EQU	6			;PRIME-ABLE REG FLAG
27CRF	EQU	7			;CRLF FLAG
28;
29CR	EQU	0DH
30LF	EQU	0AH
31ESC	EQU	1BH
32ALT	EQU	7DH
33;
34;  DISPLACEMENTS FROM IX OF HI BYTE OF REG PAIRS
35;
36;
37DUPC	EQU	-1			;(FFFF)
38DUAF	EQU	-3			;(FFFD)
39DUBC	EQU	-5			;(FFFB)
40DUDE	EQU	-7			;(FFF9)
41DUHL	EQU	-9			;(FFF7)
42DUSP	EQU	-11			;(FFF5)
43DUIX	EQU	-13			;(FFF3)
44DUIY	EQU	-15			;(FFF1)
45DUIN	EQU	-17			;(FFEF)        I & THE INTERRUPT FF
46DUAF2	EQU	-19			;(FFED)
47DUBC2	EQU	-21			;(FFEB)
48DUDE2	EQU	-23			;(FFE9)
49DUHL2	EQU	-25			;(FFE7)
50;
51LENRGS	EQU	DUPC-DUHL2+2
52;
53;
54;
55;
56
57	ORG	0E000H
58;
59; ENTER THE MONITOR FROM RESET.
60; COLD START ENTRY. INITIALIZES THE UART
61; AND ZEROES THE BREAKPOINT STACK POINTER.
62; ALTERS THE A-REGISTER. SAVES ALL OTHER
63; REGISTERS EXCEPT THE PROGRAM COUNTER,
64; BUT DOES NOT DISPLAY THEM.
65
66CSTART: LD  	A,1
67	OUT 	(40H),A			;SELECT BANK B
68	PUSH	AF			;SIMULATE UPC
69	PUSH	AF			;USER-F-REGISTER
70	JR	COMMON
71; WARM START ENTRY.  INITIALIZES THE BREAKPOINT
72; STORAGE POINTER.  SAVES ALL REGISTERS EXCEPT
73; THE PROGRAM COUNTER, BUT DOES NOT DISPLAY THEM.
74
75WSTART:	PUSH	AF			;SIMULATE UPC
76	PUSH	AF			;UAF
77	LD	A,80H			;FLAG:
78	JR	COMMON			;WARM-START ENTRY
79;
80; CHECK INPUT & RETURN WITH DATA IF READY.
81;
82CHKIN:	IN	A,(STAT)
83	AND	DAV
84	RET	Z
85	IN	A,(DATA)
86	RET
87;
88;
89; GET CHARACTER FROM INPUT.
90;
91GBYTE:	CALL	CHKIN
92	JR	Z,GBYTE
93	AND	7FH
94	RET
95;
96;
97; PRINT CHARACTER.
98;
99PBYTE:	PUSH	AF
100PBY1:	IN	A,(STAT)
101	AND	TBE
102	JR	Z,PBY1
103	POP	AF
104	OUT	(DATA),A
105	RET
106;
107;
108; SELECT DEVICE A & INITIALIZE ITS BAUD RATE.
109; ENTER WITH A=1.
110;
111INIT:	OUT	(BPARLP),A		;SELECT DEVICE A
112	OUT	(BCMNDP),A		;RESET DEVICE B
113;					;[CONTINUE BELOW]
114;
115;
116; INITIALIZE BAUD RATE OF THE CURRENT DEVICE.
117;
118; PUSH CARRIAGE-RETURN TO SELECT THE PROPER BAUD
119; RATE FOR THE CURRENT TERMINAL. (THE MAXIMUM
120; NUMBER OF CARRIAGE-RETURNS REQUIRED IS FOUR.)
121;
122; WITH THE CROMEMCO TUART ANY OF THE FOLLOWING
123; BAUD RATES CAN BE SELECTED:
124; 19200, 9600, 4800, 2400, 1200, 300, 150, 110.
125;
126; WITH THE 3P+S:	2400, 300, 110.
127;
128; TWO CARRIAGE-RETURNS ARE REQUIRED FOR
129; ANY UART WITH A FIXED BAUD RATE.
130;
131INITBAUD: LD	HL,BAUDRS
132	LD	C,ABAUDP
133	LD	A,11H			;OCTUPLE THE CLOCK
134IT1:	OUT	(ACMNDP),A		;& RESET CURRENT DEVICE
135	OUTI
136	CALL	GBYTE
137	CALL	GBYTE
138	CP	CR
139	LD	A,1			;SLOW THE CLOCK
140	JR	NZ,IT1
141	RET
142;
143;
144; BREAKPOINT ENTRY. INITIALIZES	NOTHING.
145; SAVES	ALL REGISTERS AND DISPLAYS THEM.
146;
147SVMS:	EX	(SP),HL			;ADJUST BRKPT
148	DEC	HL			;RET ADDR
149	EX	(SP),HL
150	PUSH	AF			;UAF
151	SUB	A			;FLAG:
152					;BREAKPOINT ENTRY;
153;
154;
155COMMON:	PUSH	BC			;UBC
156	LD	B,A			;ENTRY FLAG
157	PUSH	DE			;UDE
158	PUSH	HL			;UHL
159;
160; PLACE SYS STACK AT HIGHEST PAGE OF
161; AVAILABLE RAM.
162; ALLOW	ROOM FOR TEMP STORAGE.
163;
164	LD	HL,00FFH-TEMPS
165COM1:	DEC	H
166	LD	A,(HL)
167	INC	(HL)
168	CP	(HL)			;DID IT CHANGE?
169	JR	Z,COM1
170	DEC	(HL)			;YES. RESTORE IT.
171;
172	LD	A,B			;ENTRY FLAG
173	EX	DE,HL
174	LD	HL,9
175	ADD	HL,SP			; -> UPC, HI BYTE
176	LD	BC,10
177	LDDR
178;
179	INC	DE			;-> UHL,LO ON SYS STK
180	EX	DE,HL
181	LD	SP,HL			;CURRENT SYS SP
182	EX	DE,HL
183	LD	BC,DUPC-DUHL+3
184	ADD	HL,BC			;HL = USER SP
185	PUSH	HL			;USP
186	PUSH	IX			;UIX
187	PUSH	IY			;UIY
188	EX	DE,HL
189	ADD	HL,BC
190	LD	C,L			;SAVE
191	DEC	HL
192	PUSH	HL
193	POP	IX
194	CP	1			;ENTRY?
195	JR	C,COM3			;SKIP IF VIA BP.
196	LD	(HL),C			;BP PNTR, LO BYTE
197	INC	HL
198	LD	(HL),0			;BP-STACK ENDMARK
199; INITIALIZE THE TUART IF ENTRY WAS VIA RESET.
200; (A CONTAINS 1.)
201;
202	CALL	Z,INIT
203;
204COM3:	LD	A,I
205	LD	H,A
206	LD	L,0
207	JP	PO,COM4
208	INC	L
209COM4:	PUSH	HL			;UIN
210	EX	AF,AF'
211	PUSH	AF			;UAF'
212	EX	AF,AF'
213	EXX
214	PUSH	BC			;UBC'
215	PUSH	DE			;UDE'
216	PUSH	HL			;UHL'
217	EXX
218;
219;IF CY IS SET, ENTRY WAS VIA A BREAKPOINT
220	LD	HL,HEAD
221	CALL	NC,PMSG
222	LD	BC,(('P'+CASE) < 8)+86H ;IF BP ENTRY,
223	CALL	C,SUBR3			;DISPLAY THE PC.
224;
225;
226;CLEAR ALL BREAKPOINTS
227;
228CLBP:	PUSH	IX
229	POP	HL			;POINTS TO BPSP,LO
230	LD	L,(HL)			;BPSP NOW IN HL
231;
232CL1:	LD	A,(HL)			;BP STK EMPTY?
233	CP	BPMRK			;IF BPMRK, BP IS SET
234	JR	NZ,CL2
235;
236	INC	(HL)			;BP-ERASED MARK
237	DEC	HL
238	LD	D,(HL)
239	DEC	HL
240	LD	E,(HL)
241	DEC	HL
242	LDD				;RESTORE MEM CONTENTS
243	JR	CL1
244;
245CL2:	LD	A,L
246	DEC	HL
247	LD	(HL),A			;ADJUST BPSP
248;
249	LD	DE,-LENRGS		;FOR THE BENEFIT
250	ADD	HL,DE			;OF ERROR & ESCPE
251	LD	SP,HL			;RE-INITIALIZE SP
252;
253;
254;GET 1-BYTE COMMAND.
255;RETURNS VALUE IN HL & JUMPS TO THAT ADDR.
256;
257	CALL	CRLF
258CMND:	LD	DE,CMND			;SET-UP RETURN
259	PUSH	DE
260CMND1:	LD	HL,PRMPT		;RE-ENTRY POINT
261	CALL	PMSG			;FOR RECURSION
262;HL NOW PNTS TO THE COMMAND TABLE.
263;
264;GET THE COMMAND.
265;DE GETS THE FIRST ALPHA CHAR LESS 'D'.
266
267	CALL	SKSG0			;GET NON-SPACE
268	RET	Z			;IF CR, IGNORE.
269	SUB	'D'+CASE		; < 'D'?
270	JR	C,ERROR
271	CP	'W'-'D'+1		; > 'W'?
272	JR	NC,ERROR
273	LD	E,A
274	LD	D,0
275;
276	LD	C,D			;INITIALIZE FOR SUBR
277	EX	DE,HL
278	ADD	HL,HL			;TIMES 2
279	ADD	HL,DE			; + TBL ADDR
280	LD	E,(HL)
281	INC	HL
282	LD	D,(HL)
283	EX	DE,HL
284	CALL	SKSG0			;NEXT CMND GHAR
285	CP	'M'+CASE		; (USED IN SUBST & DISPL)
286	JP	(HL)
287;
288;
289; ERROR & ESCAPE. RETURNS TO CMND WITH SP
290; POINTING TO SAVED-REG AREA (UHL').
291
292ERROR:	LD	A,'?'
293	CALL	PCHR
294ESCPE:	JR	CLBP			;CLEAR ANY BRKPTS
295;
296;
297; PROGRAM PROMS. ABORTS IF DESTINATION
298; IS NOT ON A 1K (400H) BOUNDARY, OR IF SWATH
299; WIDTH IS NOT A MULTIPLE OF 1K.
300;
301;
302PROG:	CALL	L3NCR
303	LD	A,B			;ARE INCREMENT &
304	OR	D			;DESTINATION BOTH
305	AND	3			;MULTIPLES OF
306	OR	C			;1024?
307	OR	E
308ERRV1:	JR	NZ,ERROR		;ERROR VECTOR
309;
310	PUSH	HL			;SOURCE
311	LD	HL,320			;# OF ITERATIONS
312PR1:	EX	(SP),HL
313	CALL	MVE			;MOVE IT
314	EX	(SP),HL
315	DEC	HL			;ITERATION CT
316	LD	A,H
317	OR	L
318	JR	NZ,PR1
319	POP	HL
320	JR	VRFY			;VERIFY IT
321;
322;
323;PRINT THE 2 BYTES IN (HL) & (HL-1)
324;DECREMENTS HL BY 2. ALTERS A.
325;PRESERVES OTHER REGS.
326;
327P2NMS:	CALL    PNM
328	DEC     HL
329	CALL    PNM
330	DEC     HL	  		; (CONTINUE BELOW)
331;
332;
333;PRINT	SPACE. ALTERS A.
334;
335SPACE:	LD A,20H	  		; (CONTINUE BELOW)
336;
337;
338;PRINT THE CHARACTER IN THE A-REGISTER.
339;(CHKS INPUT FOR ESC.)	PRESERVES ALL REGS.
340;
341PCHR:	PUSH	AF	         	;SAVE THE CHAR
342PC1:	AND	7FH
343	CP	ESC
344	JR	Z,ESCPE
345	CP	ALT			;ALT MODE?
346	JR	Z,ESCPE
347	CALL	CHKIN
348	JR	NZ,PC1
349;
350PC2:	POP	AF
351	PUSH	HL
352	PUSH	AF
353	AND	7FH
354	CALL	PBYTE
355	LD	HL,LFNN
356	CP	CR
357	CALL	Z,PMSG
358	CP	'<'			;RECURSIVE CALL
359	JR	NZ,PC3			;ON CMND?
360	POP	AF
361	LD	A,CR			;YES. CONVERT
362	PUSH	AF			;'<' TO A CR.
363	PUSH	DE
364	PUSH	BC
365	CALL	CMND1
366	POP	BC
367	POP	DE
368PC3:	POP	AF
369	POP	HL
370	RET
371;
372;
373; GET CHARACTER. RETURNS IT IN A.
374; ALTERS F.
375;
376GCHR:	CALL	GBYTE
377	CALL	PCHR
378	JR	Z,GCHR			;IF NULL DON'T RETURN
379	RET
380;
381;
382; CRLF.	ALTERS A ONLY.
383;
384CRLF:	LD	A,CR
385	JR	PCHR
386;
387;
388; LOADS	HL WITH	SOURCE ADDR, BC	& DE
389; WITH THE INCREMENT. ENDS WITH A CRLF.
390;
391L2NCR0:	SUB	A
392
393L2NCR:	CALL	LD2N
394;
395; SKIP INITIAL SPACES.
396; IF DELIMITER NOT A CR, ERROR
397;
398SKSGCR:	CALL	SKSG			;WAIT FOR NON-SPACE
399	JR	NZ,ERRV1		;IF NOT CR, ERROR
400	EX	DE,HL
401	RET
402;
403;
404; PRINT THE NUMBER IN HL, FOLLOWED BY A COLON.
405; PRESERVES ALL REGISTERS EXCEPT A.
406;
407PCADDR:	CALL	CRLF
408;
409PADDR:	CALL	PNHL
410	LD	A,':'
411	JR	PCHR
412;
413;
414; COMMAND
415;
416VERIF:	CALL	L3NCR			;GET 3	OPERANDS
417;
418; COMPARES TWO AREAS OF MEMORY. ENTER WITH
419; SOURCE IN HL, DESTINATION IN DE & COUNT
420; IN BC. ALTERS ALL REGISTERS.
421;
422VRFY:	LD	A,(DE)
423	CPI				;COMPARE TO SOURCE
424	DEC	HL
425	CALL	NZ,PNHL			;PRINT SOURCE ADDR
426	CALL	NZ,PSNM	  		; & CONTENTS
427	EX	DE,HL
428	CALL	NZ,PSNM	  		; & DEBT CONTENTS
429	CALL	NZ,PSNHL	  	; & DEBT ADDR
430	CALL 	NZ,CRLF
431	EX 	DE,HL
432	INC 	HL
433	INC 	DE
434	RET 	PO 			;IF BC=0, DONE.
435	JR VRFY
436;
437;
438; COMMAND
439;
440MOVE:	CALL	L3NCR			;OPERANDS
441	CALL	MVE			;MOVE IT
442	JR	VRFY
443;
444;
445; LOAD TWO NUMBERS. LOADS DE WITH THE BEGINNING
446; ADDR, N1. LOADS BC & HL WITH THE INCREMENT
447; N2-Ni+1 (OR WITH N2 IF THE OPR IS 'S').
448; RETURNS WITH LAST DELIMITER IN A.
449;
450LD2N: 	CALL	GNHL			;N1 TO HL, DELIM TO A
451	EX  	DE,HL			;SAVE N1 IN DE
452	CALL	SKSG			;GET NEXT NON-SPACE
453	CP  	'S'+CASE		;SWATH?
454	JR  	NZ,L2N1
455;
456	CALL	GNHL0			;YES. INCREMENT TO HL.
457	JR	L2N2
458
459L2N1:	CALL	GNHL	        	;INCREMENT
460	OR  	A  	         	;CLEAR CY
461	SBC 	HL,DE 	        	;N2-N1
462	INC 	HL 	         	;INCLUDE END POINT
463L2N2:	LD	B,H
464	LD  	C,L  	         	;BC GETS THE INCRM
465	RET
466;
467;
468; LOAD 3 OPERANDS. HL GETS THE SOURCE, BC
469; THE INCREMENT, AND DE	THE 3RD OPERAND.
470;
471L3NCR: CALL	LD2N
472; (CONTINUE BELOW)
473;
474;
475; ENTER WITH SPACE OR THE FIRST DIGIT
476; OF A NUMBER IN A. LOADS HL WITH
477; WITH A NEW NUMBER & THEN EXCHANGES
478; DE & HL. FINISHES WITH A CRLF.
479;
480L1NCR: CALL	GNHL	        	 ;SKIP SPACES, LOAD HL
481	JR  	SKSGCR  	         ;WAIT FOR A CR
482;
483;
484; CLEARS HL. IF	ENTERED	WITH HEX CHAR IN A,
485; SHIFTS IT INTO HL. O/W, IGNORES LEADING
486; SPACES. FIRST	CHAR MUST BE HEX. CONTINUES
487; SHIFT UNTIL A	NON-HEX	CHAR RECEIVED & THEN
488; RETURNS WITH THE LATTER IN A.
489; PRESERVES B,C,D,E.
490;
491;
492GNHL0: SUB	A
493;
494GNHL: PUSH	BC	         	;SAVE
495	LD  	HL,0  	         	;CLR BUFFER
496; STRIP LEADING	SPACES & GET CHAR
497	CALL	SKSG
498; FIRST CHAR MUST BE HEX
499	CALL	HEXSH	         	;IF HEX, SHIFT INTO HL
500	JP  	C,ERROR  	        ;O/W, ERROR
501GN1: CALL	GCHR
502	CALL	HEXSH			;IF HEX SHIFT INTO HL
503	LD  	A,B  			;RESTORE CHAR
504	JR  	NC,GN1			;IF HEX, CONTINUE
505	POP 	BC			;IF NON-HEX, DONE
506	RET
507;
508;
509; IF A CONTAINS	HEX CHAR, SHIFTS BINARY EQUIVALENT
510; INTO HL. IF NOT HEX, RET WITH CY SET. SAVES
511; ORIGINAL CHAR	IN B
512;
513HEXSH:	LD	B,A
514	SUB	'0'			; < '0'?
515	RET	C
516	ADD	A,'0'-('G'+CASE)
517	RET	C
518	SUB	'A'-'G'
519	JR	NC,HX1 			;OK IF >= 'A'
520	ADD	A,('A'+CASE)-('9'+1)
521	RET	C
522HX1:	ADD	A,'9'+1-'0'
523; THE A-REG NOW CONTAINS THE HEX DIGIT IN BINARY.
524; (THE HIGH-ORDER NIBBLE OF A IS 0.)
525HXSH4:	ADD	HL,HL 			;SHIFT 4 BITS INTO HL
526	ADD	HL,HL
527	ADD	HL,HL
528	ADD	HL,HL
529	OR	L
530	LD	L,A
531	RET
532;
533;
534; RETURNS WITH A NON-SPACE IN THE A-REG.
535; IF ENTERED WITH A-REG CONTAINING A NULL
536; OR A SPACE, GETS NEW CHARS UNTIL FIRST
537; NON-SPACE OCCURS. ALTERS AF.
538;
539SKSG0:	SUB	A
540;
541SKSG:	OR	A			;DOES A CONTAIN NULL?
542SK1:	CALL	Z,GCHR
543	CP	20H			;SPACE?
544	JR	Z,SK1
545	CP	CR
546	RET
547;
548;
549; PRINT SPACE FOLLOWED BY THE NUMBER POINTED
550; TO BY HL. ALTERS A ONLY.
551;
552PSNM:	CALL	SPACE
553;	(CONTINUE BELOW)
554
555; PRINTS THE NUMBER POINTED TO BY HL.
556; PRESERVES ALL REGISTERS BUT A.
557
558PNM:	LD	A,(HL)
559	JR	P2HEX
560;
561;
562; PRINT THE NUMBER IN HL.
563; PRESERVES ALL BUT A.
564;
565PSNHL:	CALL	SPACE
566;
567PNHL:	LD	A,H
568	CALL	P2HEX
569	LD	A,L
570;					; (CONTINUE BELOW)
571;
572;PRINT THE NUMBER IN THE A-REGISTER.
573;PRESERVES ALL REGISTERS.
574;
575P2HEX:	CALL	P1HEX
576	RRA
577P1HEX:	RRA
578	RRA
579	RRA
580	RRA
581	PUSH	AF
582	AND	0FH			;MASK
583	CP	10			; < 9?
584	JR	C,PH1
585	ADD	A,7			;A THRU F
586PH1:	ADD	A,30H			;ASCII BIAS
587	CALL	PCHR			;PRINT IT
588	POP	AF
589	RET
590;
591;
592;PRINT	MESSAGE. ENTER WITH ADDR OF MSG
593;IN HL. THE MESSAGE IS TERMINATED
594;AFTER PRINTING A CHARACTER WHOSE
595;PARITY BIT WAS SET.
596;PRESERVES FLAGS, INCREMENTS HL.
597;
598PMSG:	PUSH	AF			;SAVE
599PS1:	LD	A,(HL)
600	INC	HL
601	CALL	PCHR
602	RLA				;LAST CHARACTER?
603	JR	NC,PS1			;IF NOT, LOOP
604	POP	AF
605	RET
606;
607;
608;MOVE FROM ONE LOCATION TO ANOTHER. ENTER
609;WITH SOURCE ADDR IN HL, DEST IN DE, BYTE
610;COUNT IN BC.  PRESERVES ALL REGISTERS.
611;
612MVE:	PUSH	HL			;SOURCE
613	PUSH	DE			;DEST
614	PUSH	BC			;BYTE COUNT
615	LDIR
616	POP	BC
617	POP	DE
618	POP	HL
619	RET
620;
621;
622; COMMAND
623;
624; GO <CR> EXECUTION BEGINS AT USER PC.
625;
626; COMMAND
627;
628; GO (ADDR1>/(ADDR2> ... <ADDRN>
629; EXECUTION BEGINS AT ADDR1 WITH BREAKPOINTS SET
630; AT ADDR2,... ,ADDRN.
631
632GO:
633; B GETS NBRKPT+1 (MAX. NUMBER OF BP + 1)
634; C, THE BREAKPOINT FLAG, GETS 0 (NO HP SET)
635	LD   	BC,((NBRKPT+1) < 8)+0
636GO1:	CALL 	SKSG 	 		;WAIT FOR NON-SPACE
637	JR   	Z,RETN   	 	;RETN IF CR
638	CP	'/'	 		;BP?
639	JR   	NZ,GO3
640	LD   	C,A   	 		;SET BRKPT FLAG (2FH)
641	LD   	HL,RSTLC   	 	;TRANSFER
642	LD   	(HL),0C3H   	 	;'JP SVMS' TO
643	LD   	HL,SVMS
644	LD   	(RSTLC+1),HL   	 	;RST LOC
645	SUB  	A
646GO3:	CALL 	GNHL 	 		;GET ADDR
647	BIT  	5,C  	 		; FLAG SET?
648	EX   	DE,HL
649	PUSH 	IX
650	POP  	HL
651	JR   	Z,GO5   	 	;JUMP IF NO BP
652;
653	DEC  	B  	 		;IF TOO MANY BP,
654	JP   	Z,ERROR   	 	;ERROR.
655	LD   	L,(HL)   	 	;HL = BPSP
656;
657	INC  	HL  	 		;BUMP BPSP
658	EX   	DE,HL   	 	;DE = BPSP, HL= BP ADDR
659	LDI
660	DEC  	HL
661	LD   	(HL),0C7H+RSTLC 	;RST INSTRUCTION
662	EX   	DE,HL   	 	;HL = BPSP
663	LD   	(HL),E   	 	;BP ADDR TO STACK
664	INC  	HL
665	LD   	(HL),D
666	INC  	HL
667	LD   	(HL),BPMRK   	 	;PUNCTUATION (BP SET)
668	LD   	(IX+0),L
669	JR   	GO1
670; CHANGE USER PC
671GO5:	DEC  	HL
672	LD   	(HL),D
673	DEC  	HL
674	LD   	(HL),E
675	JR   	GO1   		 	;BACK FOR MORE
676;
677RETN:	POP  	HL  	 		;STRIP ADDR FROM STK
678	POP  	HL  	 		;UHL'
679	POP  	DE  	 		;UDE'
680	POP	BC			;UBC'
681	POP	AF			;UAF'
682	EXX
683	EX 	AF,AF'
684;
685	POP	AF			;UIN
686	LD 	I,A 			; UI
687	DI
688	JR 	NC,RT1
689	EI
690;IFF NOW RESTORED
691RT1:	POP	IY			;UIY
692	POP	IX			;UIX
693	POP	DE			;USP
694;
695;COPY THE REMAINDER OF THE SYS STACK
696;TO THE USER STACK. IF THIS TRANSFER
697;IS MADE WITHOUT ERROR, SWITCH TO THE
698;USER STACK. OTHERWISE, RETAIN THE
699;SYSTEM STACK.
700;
701	LD	HL,10
702	LD 	B,L
703	ADD	HL,SP
704	EX 	DE,HL
705RT2:	DEC	DE
706	DEC	HL
707	LD 	A,(DE)
708	LD 	(HL),A
709	CP 	(HL)
710	JR 	NZ,RT3
711	DJNZ	RT2
712	LD 	SP,HL
713;
714RT3:	POP	HL
715	POP	DE
716	POP	BC
717	POP	AF
718	RET
719
720
721;	COMMAND.  DISPLAY REGISTERS.
722;
723;	DR
724;
725; COMMAND.  DISPLAY MEMORY.
726;
727; DM <STARTING ADDR> <ENDING ADDR OR SWATH>
728;
729DISPL:	LD	BC,(('A'+CASE) < 8)+80H ;[FOR DR]
730	JR	NZ,SUBR2	 	;IF NOT 'M', DR
731;
732;
733DSPM:	CALL	L2NCR0	 		;GET OPERANDS
734DSPM1:	LD	D,16	 		;BYTE COUNT
735	CALL	PCADDR	 		;ADDRESS
736DM2:	CALL	PSNM			;MEM CONTENTS
737	CPI				;INC HL & DEC BC
738	JP	PO,CRLF
739	DEC	D
740	JR	Z,DSPM1
741	LD	A,D
742	AND	3
743	CALL	Z,SPACE
744	CALL	Z,SPACE
745	JR	DM2
746;
747;
748; COMMAND. SUBSTITUTE MEMORY LOCATION.
749;
750; SM <ADDR>
751;
752; COMMAND. SUBSTITUTE USER-REGISTER.
753;
754; S<REGISTER NAME>
755;
756; REGISTER NAMES: P [PC] , S [SP]
757; A, F, B, C, D, E, H [HL]
758; I, N [1FF], X [IX], Y [IY]
759; A',F',B',C',D',E',H' [HL'].
760;
761SUBST:	JR	NZ,SUBR			;IN NOT 'M', SR
762
763SUBM:	SUB	A
764	LD	B,A			;1-BYTE MASK
765	CALL	L1NCR
766	EX	DE,HL			;HL GETS ADDR
767SM1:	CALL	Z,PCADDR
768	CALL	Z,SPACE
769; PRINT CURRENT VALUE, REQUEST NEW VALUE &
770; PRINT IT IF GIVEN
771	CALL	GSUBV
772	RET	Z			;IF CR, DONE.
773	INC	HL
774	LD	A,7			;PRINT ADDRESS IF IT
775	AND	L			;IS A MULTIPLE OF 8
776	JR	SM1
777;
778;
779SUBR:	LD	B,A
780	CALL	GCHR
781	CP	''''
782	JR	NZ,SR2
783	INC	C			;TURN ON THE PRIME-FLAG
784SUBR2:	SUB	A
785SR2:	CALL	SKSGCR			;WAIT FOR CR
786SR3:	LD	A,B
787	SUB	'A'+CASE		;CHECK THE RANGE
788	JP	C,ERROR
789	CP	'Y'-'A'+1
790	JP	NC,ERROR
791	LD	E,A
792	LD	D,0
793	LD	HL,RGTBL
794	ADD	HL,DE
795	LD	A,(HL)
796	OR	A
797	JR	Z,SR6	    		;IF ENTRY = 0, SKIP
798	LD	E,0
799	BIT	0,C	    		;PRIME?
800	JR	Z,SR4
801	BIT	PF,(HL)			;YES. PRIMEABLE REG?
802	JR	Z,SR6	    		;IF NOT, SKIP.
803	LD	E,DUAF-DUAF2
804SR4:	AND	1FH	    		;STRIP FLAGS FROM ENTRY
805	ADD	A,E
806	LD	E,A
807	PUSH	BC	    		;SAVE
808	LD	A,B	    		;PRINT REG NAME
809	CALL	PCHR
810	CP	'H'+CASE
811	LD	A,'L'+CASE
812	CALL	Z,PCHR
813	XOR	'L'+CASE ^ '='		;CLEAR CY, A = '='.
814	BIT	0,C	    		; PRIME?
815	JR	Z,SR5
816	LD	A,''''
817SR5:	CALL	PCHR
818	LD	B,(HL)	    		;SAVE ORIGINAL ENTRY
819	PUSH	IX
820	POP	HL	   	 	;STACK FRAME
821	SBC	HL,DE	    		;HL -> USER REG
822	CALL	GSUBV	    		;PRINT VALUE, REQUEST NEW
823	LD	A,B	    		;SAVE
824	POP	BC
825	RET	Z	    		;DONE IF CR
826;
827SR6:	INC	B	    		;NEXT REG
828	RLCA		    		;Y OR H?
829	JR	NC,SR3	    		;IF NEITHER, LOOP
830	RLCA		    		;YES, IS IT Y?
831SUBR3:	CALL	CRLF	    		; [ENTRY FOR DISPLAYING PC
832	JR	C,SR8
833	LD	B,'A'+CASE		;YES, IT IS Y.
834	INC	C	    		;TURN ON PRIME-FLAG
835	JR	SR3
836SR8:	BIT	0,C	    		;NO. H OR H'?
837	JR	Z,SR3	   		;IF H, LOOP.
838	RET		    		;IT IS H'. DONE.
839
840
841; ENTER WITH HL POINTING TO MEMORY &
842; B CONTAINING THE 1-BYTE OR 2-BYTE FLAG.
843; PRINTS SPACE, CONTENTS OF (HL), & ALSO (HL-1) FOR
844; 2-BYTE REGS, GETS SUBSTITUTION VALUE & LOADS IT.
845; RETURNS WITH Z-FLAG SET 1FF THE DELIMITER IS
846; A CARRIAGE-RETURN.
847; PRESERVES BC & HL.
848;
849GSUBV:	CALL	PNM	 		;PRINT (HL)
850	BIT	B2F,B	 		;2-BYTE REG?
851	JR	Z,GS1
852	DEC	HL
853	CALL	PNM	 		;LO BYTE
854GS1:	LD	A,C	 		;SUBST-OR-DISPLAY FLAG
855	RLCA
856	JR	C,GS2			;IF DISPLAY, EXIT.
857	LD	A,'.'
858	CALL	PCHR
859	CALL	GCHR
860	CP	'.'+1			;SUBSTITUTION?
861GS2:	CALL	C,PCHR			;IF NOT, PRINT ANOTHER.
862	JR	C,GS3
863	EX	DE,HL
864	CALL	GNHL			;NEW VALUE
865	EX	DE,HL
866	LD	(HL),E
867	BIT	B2F,B
868	JR	Z,GS3
869	INC	HL
870	LD	(HL),D
871GS3:	CP	CR
872	CALL	NZ,SPACE
873	RET
874;
875;
876;...SUBDM 00 7E 5 585 BY 5 100 DBE++
877;
878;
879; COMMAND
880; SELECT UART-A OR UART-B.
881;
882; UA
883; UB
884;
885UART:	CALL	L1NCR			;A OR B?
886	LD	A,E
887	CP	0BH
888	JR	NZ,UARTA
889	LD	A,80H
890	OUT	(APARLP),A
891	RET
892;
893UARTA:	SUB	A
894	OUT	(BPARLP),A
895	RET
896;
897;
898; COMMAND
899; READ BINARY INPUT FROM DATA PORT
900;
901READB:	CALL	L2NCR			;GET MEM ADDRS
902RB1:	CALL	CHKIN			;GET INPUT
903	JR	Z,RB1
904	LD	(HL),A			;TO MEM
905	CPI
906	RET	PO
907	JR	RB1
908;
909;
910; COMMAND
911; WRITE BINARY OUTPUT TO DATA PORT
912
913WRITB:	CALL	L2NCR			;GET MEM ADDRS
914WB1:	LD	A,(HL)
915	CALL	PBYTE
916	CPI
917	RET	PO
918	JR	WB1
919;
920;
921; COMMAND
922; PRINT NULLS ON THE CURRENT DEVICE.
923;
924; N <NUMBER-OF-NULLS>
925;
926NULLS:	CALL	L1NCR
927	LD	B,E
928	SUB	A
929N2:	CALL	PCHR
930	DJNZ	N2
931	RET
932;
933;
934; COMMAND
935; OUT <DATA-BYTE> <PORT NUMBER>
936;
937OUTP:	CALL	GNHL
938	EX	DE,HL			;E GETS DATA
939	CALL	L1NCR			;GET PORT NUMBER
940;
941	LD	C,E			; TO C
942	OUT	(C),L
943	RET
944;
945
946; BAUD RATES.
947; WITH THE CROMEMCO TUART:  19200, 9600, 4800,
948; 			2400, 1200, 300, 150, 110.
949;
950; WITH THE 3P+S: 2400, 300, 110.
951;
952;
953BAUDRS:	DEFB	94H,0CEH,0A2H,92H,88H,84H,82H,1
954;
955;
956LFNN:	DEFB	LF,0,0 | 80H
957;
958;
959PRMPT:	DEFB	(':' | 80H)
960; THE COMMAND TBL MUST IMMEDIATELY FOLLOW
961;
962;  THE	PROMPT MESSAGE
963	DEFW	DISPL			;DISPLAY: DM, DR
964	DEFW	ERROR			;E
965	DEFW	ERROR
966	DEFW	GO			;GO; GO/WITH BREAKPOINTS
967	DEFW	ERROR
968	DEFW	INITBAUD		;INITIALIZE BAUD RATE
969	DEFW	ERROR			;J
970	DEFW	ERROR			;K
971	DEFW	ERROR			;L
972	DEFW	MOVE			;MOVE A BLOCK OF MEMORY
973	DEFW	NULLS			;NULLS
974	DEFW	OUTP			;OUTPUT
975	DEFW	PROG			;PROGRAM
976	DEFW	ERROR			;Q
977	DEFW	READB			;READ BINARY OR ASCII
978	DEFW	SUBST			;SUBSTITUTE: SM, SA, SB.
979	DEFW	ERROR			;T
980	DEFW	UART			;UART: UA, UB
981	DEFW	VERIF			;VERIFY BLOCKS OF MEMORY
982	DEFW	WRITB			;WRITE BINARY OR ASCII
983;
984PM	EQU	1 < PF			;PRIMEABLE-REG MASK
985B1M	EQU	0			;1-BYTE REG MASK
986B2M	EQU	1 < B2F			;2-BYTE REG MASK
987CRM	EQU	1 < CRF			;CARRIAGE-RETURN MASK
988
989RGTBL:	DEFB	-DUAF | PM		;A
990	DEFB	-DUBC | PM		;B
991	DEFB	-DUBC+1 | PM		;C
992	DEFB	-DUDE | PM		;D
993	DEFB	-DUDE+1 | PM		;E
994	DEFB	-DUAF+1 | PM		;F
995	DEFB	0
996	DEFB	-DUHL | PM | B2M | CRM	;H [HL]
997	DEFB	-DUIN | B1M		;I
998	DEFB	0
999	DEFB	0
1000	DEFB	0
1001	DEFB	0
1002	DEFB	-DUIN+1 | B1M		;N [INTERRUPT FF]
1003	DEFB	0
1004	DEFB	-DUPC | B2M		;PC
1005	DEFB	0
1006	DEFB	0
1007	DEFB	-DUSP | B2M		;SP
1008	DEFB	0
1009	DEFB	0
1010	DEFB	0
1011	DEFB	0
1012	DEFB	-DUIX | B2M		;X [IX]
1013	DEFB	-DUIY | B2M | CRM 	;Y [IY]
1014;
1015;
1016HEAD:	DEFB	CR,CR, 'CROMEMCO ZM1.',('4' | 80H)
1017	END	CSTART
1018