1;	<< ZAPPLE 2-K MONITOR SYSTEM >>
2;		by
3;
4;	TECHNICAL DESIGN LABS, INC.
5;	RESEARCH PARK
6;	PRINCETON, NEW JERSEY  08540
7;
8;	COPYRIGHT JULY 1976 BY TDL INC.
9;
10;	ASSEMBLED BY ROGER AMIDON
11;
12; SEPTEMBER 2017 BY UDO MUNK:
13;	MODIFIED TO ZILOG/MOSTEK SYNTAX TO ASSEMBLE WITH Z80ASM
14;	FIXED TYPOS AND BUGS
15;	CHANGED TYPEWRITER I/O TO MITS 2SIO CHANNEL A
16;	CHANGED CASSETTE I/O TO MITS ACR SIO
17;
18; USE Z80ASM VERSION 1.8, WON'T ASSEMBLE CORRECT WITH VERSIONS BEFORE!
19;
20;
21BASE	EQU	0F000H
22USER	EQU	BASE+800H
23;
24	TITLE	<Zapple Monitor, Version 1.11, Dec. 18, 1976>
25;
26RST7	EQU	38H	     ;RST 7 (LOCATION FOR TRAP)
27;IOBYT	EQU	2	     ;R/W PORT FOR TEMP. STORAGE
28IOBYT	EQU	0EFFFH	     ;MEMORY LOCATION FOR TEMP. STORAGE
29;SENSE	EQU	3	     ;PORT FOR INITIAL I/O CONFIGURATION (IN)
30SWITCH	EQU	0FFH	     ;FRONT PANEL SENSE SWITCHES
31;RCP	EQU	SENSE	     ;READER CONTROL PORT (OUT)
32NN	EQU	0	     ;"I" REGISTER INITIAL VALUE
33;
34;	EXTERNAL EQUATES
35;
36;	NAME	ZAPPLE
37;	EXT	COLOC
38;	EXT	LNLOC
39;	EXT	LULOC
40;	EXT	PTPL
41;	EXT	PULOC
42;	EXT	CSLOC
43;	EXT	CILOC
44;	EXT	RPTPL
45;	EXT	RULOC
46;
47;
48;	<I/O DEVICES>
49;
50;-TELEPRINTER
51;
52TTI	EQU	11H	     ;DATA IN PORT
53TTO	EQU	11H	     ;DATA OUT PORT
54TTS	EQU	10H	     ;STATUS PORT (IN)
55TTS2	EQU	12H	     ;STATUS PORT MITS 2SIO B
56TTYDA	EQU	01H	     ;DATA AVAILABLE MASK BIT
57TTYBE	EQU	02H	     ;XMTR BUFFER EMPTY MASK
58;
59;-C.R.T. SYSTEM
60;
61CRTI	EQU	51H	     ;DATA PORT (IN)
62CRTS	EQU	50H	     ;STATUS PORT (IN)
63CRTO	EQU	51H	     ;DATA PORT (OUT)
64CRTDA	EQU	40H	     ;DATA AVAILABLE MASK
65CRTBE	EQU	80H	     ;XMTR BUFFER EMPTY MASK
66;
67;-CASSETTE SYSTEM
68;
69RCSD	EQU	07H	     ;DATA IN PORT
70RCSS	EQU	06H	     ;STATUS PORT (IN)
71RCSDA	EQU	01H	     ;DATA AVAILABLE MASK
72PCASO	EQU	07H	     ;DATA PORT (OUT)
73PCASS	EQU	06H	     ;CONTROL PORT (OUT)
74PCSBE	EQU	80H	     ;XMTR BUFFER EMPTY MASK
75;
76;	<CONSTANTS>
77;
78FALSE	EQU	0	     ;ISN'T SO
79TRUE	EQU	~FALSE       ;IT IS SO
80CR	EQU	0DH	     ;ASCII CARRIAGE RETURN
81LF	EQU	0AH	     ;ASCII LINE FEED
82BELL	EQU	7	     ;DING
83RUB	EQU	0FFH	     ;RUB OUT
84FIL	EQU	00	     ;FILL CHARACTER AFTER CRLF
85MAX	EQU	7	     ;NUMBER OF QUES IN EOF
86;
87;	<I/O CONFIGURATION MASKS>
88;
89CMSK	EQU	11111100B    ;CONSOLE DEVICE
90RMSK	EQU	11110011B    ;STORAGE DEVICE (IN)
91PMSK	EQU	11001111B    ;STORAGE DEVICE (OUT)
92LMSK	EQU	00111111B    ;LIST DEVICE
93;
94;
95;-CONSOLE CONFIGURATION
96CTTY	EQU	0	     ;TELEPRINTER
97CCRT	EQU	1	     ;C.R.T.
98BATCH	EQU	2	     ;READER FOR INPUT, LIST FOR OUTPUT
99CUSE	EQU	3	     ;USER DEFINED
100;
101;-STORAGE INPUT CONFIGURATION
102RTTY	EQU	0	     ;TELEPRINTER READER
103RPTR	EQU	4	     ;HIGH-SPEED RDR (EXTERNAL ROUTINE)
104RCAS	EQU	8	     ;CASSETTE
105RUSER	EQU	0CH	     ;USER DEFINED
106;
107;-STORAGE OUTPUT CONFIGURATION
108PTTY	EQU	0	     ;TELEPRINTER PUNCH
109PPTP	EQU	10H	     ;HIGH-SPEED PUNCH (EXTERNAL ROUTINE)
110PCAS	EQU	20H	     ;CASSETTE
111PUSER	EQU	30H	     ;USER DEFINED
112;
113;-LIST DEVICE CONFIGURATION
114LTTY	EQU	0	     ;TELEPRINTER PRINTER
115LCRT	EQU	40H	     ;C.R.T. SCREEN
116LINE	EQU	80H	     ;LINE PRINTER (EXTERNAL ROUTINE)
117LUSER	EQU	0C0H	     ;USER DEFINED
118;
119;
120;	VECTOR FOR USER DEFINED ROUTINES
121;
122CILOC	EQU	USER	     ;CONSOLE INPUT
123COLOC	EQU	CILOC+3	     ;CONSOLE OUTPUT
124RPTPL	EQU	COLOC+3	     ;HIGH-SPEED READER
125RULOC	EQU	RPTPL+3	     ;USER DEFINED STORAGE (INPUT)
126PTPL	EQU	RULOC+3	     ;HIGH-SPEED PUNCH
127PULOC	EQU	PTPL+3	     ;USER DEFINED STORAGE (OUTPUT)
128LNLOC	EQU	PULOC+3	     ;LINE PRINTER
129LULOC	EQU	LNLOC+3	     ;USER DEFINED PRINTER
130CSLOC	EQU	LULOC+3	     ;CONSOLE INPUT STATUS ROUTINE
131J	EQU	CSLOC+3
132;
133;	PROGRAM CODE BEGINS HERE
134;
135;
136	ORG	BASE
137	JP	BEGIN	     ;GO AROUND VECTORS
138;
139;	<VECTOR FOR CALLING PROGRAMS>
140;
141; THESE VECTORS MAY BE USED BY USER WRITTEN
142; PROGRAMS TO SIMPLIFY THE HANDLING OF I/O
143; FROM SYSTEM TO SYSTEM.  WHATEVER THE CURRENT
144; ASSIGNED DEVICE, THESE VECTORS WILL PERFORM
145; THE REQUIRED I/O OPERATION, AND RETURN TO
146; THE CALLING PROGRAM.  (RET)
147;
148; THE REGISTER CONVENTION USED FOLLOWS-
149;
150; ANY INPUT OR OUTPUT DEVICE
151;	CHARACTER TO BE OUTPUT IN 'C' REGISTER.
152;	CHARACTER WILL BE IN 'A' REGISTER UPON
153;	RETURNING FROM AN INPUT OR OUTPUT.
154; 'CSTS'-
155;	RETURNS TRUE (0FFH IN 'A' REG.) IF THERE IS
156;	SOMETHING WAITING, AND ZERO (00) IF NOT.
157; 'IOCHK'-
158;	RETURNS WITH THE CURRENT I/O CONFIGURATION
159;	BYTE IN 'A' REGISTER.
160; 'IOSET'-
161;	ALLOWS A PROGRAM TO DYNAMICALLY ALTER THE
162;	CURRENT I/O CONFIGURATION, AND REQUIRES
163;	THE NEW BYTE IN 'C' REGISTER.
164; 'MEMCK'-
165;	RETURNS WITH THE HIGHEST ALLOWED USER
166;	MEMORY LOCATION. 'B'=HIGH BYTE, 'A'=LOW.
167; 'TRAP'-
168;	THIS IS THE 'BREAKPOINT' ENTRY POINT,
169;	BUT MAY BE 'CALLED'. IT WILL SAVE
170;	THE MACHINE STATE. RETURN CAN BE MADE WITH
171;	A SIMPLE 'G[CR]' ON THE CONSOLE.
172;
173	JP	CI	     ;CONSOLE INPUT
174	JP	RI	     ;READER INPUT
175	JP	CO	     ;CONSOLE OUTPUT
176	JP	PUO	     ;PUNCH OUTPUT
177	JP	LO	     ;LIST OUTPUT
178	JP	CSTS	     ;CONSOLE STATUS
179	JP	IOCHK	     ;I/O CHECK
180	JP	IOSET	     ;I/O SET
181	JP	MEMCK	     ;MEMORY LIMIT CHECK
182TRAP:	JP	RESTART	     ;BREAKPOINT
183;
184;	ANNOUNCEMENT OF MONITOR NAME & VERSION
185MSG:	DEFB	CR,LF,FIL,FIL,FIL
186	DEFB	'Zapple V'
187	DEFB	'1.1'
188MSGL	EQU	$-MSG
189;
190;	LET US BEGIN
191;
192; *NOTE- THE CODE UP TO THE 'IN SENSE' MAY
193; BE REPLACED BY ENOUGH CODE TO INITIALIZE
194; AN ACIA OR SIO DEVICE. ADDITIONAL DEVICES
195; MAY BE INITIALIZED USING THE 'Q' COMMAND.
196; (OR STANDARD ROUTINES FOR INITILIZATION
197; MAY BE LOADED & EXECUTED IN THE USER AREA).
198;
199BEGIN:
200	LD	A,3	     ;RESET BOTH MITS 2SIO ACIA
201	OUT	(TTS),A
202	OUT	(TTS2),A
203	LD	A,15H	     ;SET BOTH MITS 2SIO ACIA TO 8N1
204	OUT	(TTS),A
205	OUT	(TTS2),A
206;
207;	LD	A,NN	     ;FOR 'I' REG. IF NEEDED.
208;	LD	I,A
209;	NOP		     ;SPARE BYTE
210;	XOR	A	     ;CLEAR READER CONTROL PORT
211;	OUT	(RCP),A
212;	IN	A,(SENSE)    ;INITIALIZE I/O CONFIGURARTION
213;	OUT	(IOBYT),A
214;
215	IN	A,(SWITCH)   ;INITALIZE I/O CONFIGURATION
216	LD	(IOBYT),A    ;  FROM FRONT PANEL SENSE SWITCHES
217;
218	LD	SP,AHEAD-4   ;SET UP A FAKE STACK
219	JP	MEMSIZ+1     ;GET MEMORY SIZE
220	DEFW	AHEAD
221AHEAD:	LD	SP,HL	     ;SET TRUE STACK
222	EX	DE,HL
223	LD	BC,ENDX-EXIT
224	LD	HL,EXIT
225	LDIR		     ;MOVE TO RAM
226	EX	DE,HL
227	LD	BC,-5FH	     ;SET UP A USER'S STACK VALUE
228	ADD	HL,BC
229	PUSH	HL	     ;PRE-LOAD USER'S STACK VALUE
230	LD	HL,0	     ;INITIALIZE OTHER REGISTERS
231	LD	B,10	     ; (16 OF THEM)
232STKIT:	PUSH	HL	     ; TO ZERO
233	DJNZ	STKIT
234HELLO:	LD	B,MSGL	     ;SAY HELLO TO THE FOLKS
235	CALL	TOM	     ;OUTPUT SIGN-ON MSG
236START:	LD	DE,START     ;MAIN 'WORK' LOOP
237	PUSH	DE	     ;SET UP A RETURN TO HERE
238	CALL	CRLF
239	LD	C,'>'
240	CALL	CO
241STARO:	CALL	TI	     ;GET A CONSOLE CHARACTER
242	AND	7FH	     ;IGNORE NULLS
243	JR	Z,STARO	     ;GET ANOTHER
244	SUB	'A'	     ;QUALIFY THE CHARACTER
245	RET	M	     ;<A
246	CP	'Z'-'A'+1
247	RET	NC	     ;>Z
248	ADD	A,A	     ;A*2
249	LD	B,0
250	LD	C,A	     ;POINT TO PLACE ON TABLE
251	LD	HL,TBL	     ;POINT TO COMMAND TABLE
252	ADD	HL,BC	     ;ADD IN DISPLACEMENT
253	LD	E,(HL)
254	INC	HL
255	LD	D,(HL)
256	EX	DE,HL	     ;D&E=ROUTINE ADDRESS
257	LD	C,2	     ;SET C UP
258	JP	(HL)	     ;GO EXECUTE COMMAND
259;
260;		<COMMAND BRANCH TABLE>
261;
262TBL:
263	DEFW	ASSIGN	    ;A - ASSIGN I/O
264	DEFW	BYE	    ;B - SYSTEM SHUT-DOWN
265	DEFW	COMP	    ;C - COMPARE MEMORY VS. READER INPUT
266	DEFW	DISP	    ;D - DISPLAY MEMORY ON CONS. IN HEX
267	DEFW	EOF	    ;E - END OF FILE TAG FOR HEX DUMPS
268	DEFW	FILL	    ;F - FILL MEMORY WITH A CONSTANT
269	DEFW	GOTO	    ;G - GOTO [ADDR]<,>BREAKPOINTS (2)
270	DEFW	HEXN	    ;H - HEX MATH. <SUM>,<DIFFERENCE>
271;	DEFW	J	    ;I * USER DEFINED, INSERT VECTOR
272	DEFW	ERROR
273	DEFW	TEST	    ;J - NON-DESTRUCTIVE MEMORY TEST
274;	DEFW	J+3	    ;K * USER DEFINED, INSERT VECTOR
275	DEFW	ERROR
276	DEFW	LOAD	    ;L - MOVE A BINARY FORMAT FILE
277	DEFW	MOVE	    ;M - MOVE BLOCKS OF MEMORY
278	DEFW	NULL	    ;N - PUNCH NULLS ON PUNCH DEVICE
279;	DEFW	J+6	    ;O * USER DEFINED, INSERT VECTOR
280	DEFW	ERROR
281	DEFW	PUTA	    ;P - 'PUT' ASCII INTO MEMORY.
282	DEFW	QUERY	    ;Q - QI(N)=DISP. N; QO(N,V)=OUT N,V
283	DEFW	READ	    ;R - READ A HEX FILE (W/CHECKSUMS)
284	DEFW	SUBS	    ;S - SUBSTITUTE &/OR EXAMINE MEMORY
285	DEFW	TYPE	    ;T - TYPE MEMORY IN ASCII
286	DEFW	UNLD	    ;U - MEMORY TO PUNCH (BINARY FORMAT)
287	DEFW	VERIFY	    ;V - COMPARE MEMORY AGAINST MEMORY
288	DEFW	WRITE	    ;W - MEMORY TO PUNCH (HEX FORMAT)
289	DEFW	XAM	    ;X - EXAMINE & MODIFY CPU REGISTERS
290	DEFW	WHERE	    ;Y - FIND SEQUENCE OF BYTES IN RAM
291	DEFW	SIZE	    ;Z - ADDRESS OF LAST R/W LOCATION
292;
293;
294;
295;	THIS ROUTINE CONTROLS THE CONFIGURATION
296; OF THE VARIOUS I/O DRIVERS & DEVICES. THIS IS
297; ACCOMPLISHED VIA A HARDWARE READ/WRITE PORT.
298;	THIS PORT IS INITIALIZED UPON SIGN-ON
299; BY THE VALUE READ ON PORT 'SENSE'.  IT MAY BE
300; DYNAMICALLY MODIFIED THROUGH CONSOLE COMMANDS.
301;
302; THE VALUE ON THE 'IOBYT' PORT REPRESENTS THE
303; CURRENT CONFIGURATION.  IT IS STURCTURED THUSLY:
304;
305; 000000XX - WHERE XX REPRESENTS THE CURRENT CONSOLE
306; 0000XX00 - WHERE XX REPRESENTS THE CURRENT READER
307; 00XX0000 - WHERE XX REPRESENTS THE CURRENT PUNCH
308; XX000000 - WHERE XX REPRESENTS THE CURRENT LISTER
309;
310; WHEN USING A MEMORY LOCATION FOR IOBYT, THE
311; POLARITY IS REVERSED.  FOR AN I/O PORT,
312; WHEN XX = 11, THE DEVICE IS ALWAYS THE
313; TELEPRINTER.  WHEN XX = 00, THE DEVICE IS ALWAYS
314; USER DEFINED.  SEE OPERATOR'S MANUAL FOR FURTHER
315; DETAILS.
316;
317ASSIGN:	CALL	TI	     ;GET DEVICE NAME
318	LD	HL,LTBL	     ;POINT TO DEVICE TABLE
319	LD	BC,400H	     ;4 DEVICES TO LOOK FOR
320	LD	DE,5	     ;4 DEV. + IDENT.
321ASS0:	CP	(HL)	     ;LOOK FOR MATCH
322	JR	Z,ASS1
323	ADD	HL,DE	     ;GO THRU TABLE
324	INC	C	     ;KEEP TRACK OF DEVICE
325	DJNZ	ASS0
326	JR	ASERR	     ;WRONG IDENTIFIER
327ASS1:	LD	E,C	     ;SAVE DEVICE NUMBER
328ASS2:	CALL	TI	     ;SCAN PAST '='
329	CP	'='
330	JR	NZ,ASS2
331	CALL	TI	     ;GET NEW ASSIGNMENT
332	LD	BC,400H	     ;4 POSSIBLE ASSIGNMENTS
333ASS3:	INC	HL	     ;POINT TO ASSIGNMENT NAME
334	CP	(HL)	     ;LOOK FOR PROPER MATCH
335	JR	Z,ASS4	     ;MATCH FOUND
336	INC	C	     ;KEEP TRACK OF ASSIGNMENT NMBR
337	DJNZ	ASS3
338ASERR:	JP	ERROR	     ;NO MATCH, ERROR
339ASS4:	LD	A,3	     ;SET UP A MASK
340	INC	E
341ASS5:	DEC	E	     ;DEVICE IN E
342	JR	Z,ASS6	     ;GOT IT
343	SLA	C	     ;ELSE MOVE MASKS
344	SLA	C
345	RLA
346	RLA		     ;A=DEVICE MASK
347	JR	ASS5
348ASS6:	CPL		     ;INVERT FOR AND'ING
349	LD	D,A	     ;SAVE IN D
350ASS7:	CALL	PCHK	     ;WAIT FOR [CR]
351	JR	NC,ASS7
352	CALL	IOCHK	     ;GET PRESENT CONFIGURATION
353	AND	D	     ;MODIFY ONLY SELECTED DEVICE
354	OR	C	     ;'OR' NEW BIT PATTERN
355	LD	C,A	     ;NEW CONFIGURATION
356;
357; THIS ALLOWS USER PROGRAMS TO MODIFY
358; THE I/O CONFIGURATIMN DYNAMICALLY
359; DURING EXECUTION.
360;
361IOSET:	LD	A,C	     ;NEW I/O BYTE PASSED IN C REG
362;	CPL		     ;WE SAVE THE INVERTED BYTE
363;	OUT	(IOBYT),A    ;IN AN I/O PORT LATCH
364	LD	(IOBYT),A    ;SAVE NEW I/O BYTE IN MEMORY
365	RET
366;
367; THIS RETURNS THE CURRENT I/O
368; CONFIGURATION IN THE A REG.
369;
370IOCHK:	;IN	A,(IOBYT)    ;GET SAVED VALUE
371;	CPL		     ;AND INVERT IT AGAIN
372	LD	A,(IOBYT)    ;GET SAVED VALUE
373	RET
374;
375; THIS ROUTINE IS USED AS A SIMPLE MEANS TO PREVENT
376; UNAUTHORIZED SYSTEM OPERATION. THE SYSTEM LOCKS UP,
377; MONITORING FOR A 'CONT.-SHIFT-N', AT WHICH TIME IT
378; WILL SIGN-ON AGAIN. NO REGISTER ASSIGNMENTS OR I/O
379; CONFIGURATIONS WILL BE ALTERED.
380;
381BYE:	CALL	CRLF
382BY1:	CALL	KI
383	CP	1EH	     ;CONTROL-SHIFT-N
384	JR	NZ,BY1
385	POP	DE	     ;REMOVE THE RETURN
386	JP	HELLO	     ;AND SIGN-ON AGAIN
387;
388; THIS ALLOWS ENTERING OF ASCII TEXT INTO MEMORY
389; FROM THE CONSOLE DEVICE. THE PARITY BIT IS CLEARED,
390; AND ALL WILL BE STORED EXCEPT THE BACK-ARROR [_]
391; WHICH DELETES THE PREVIOUS CHARACTER, AND
392; CONTROL-D, WHICH RETURNS CONTROL TO THE MONITOR.
393; THIS COMMAND, COMBINED WITH THE 'Y' COMMAND,
394; PROVIDES A RUDIMENTARY TEXT PROCESSING ABILITY.
395;
396PUTA:	CALL	EXPR1	     ;GET THE STARTING ADDR.
397	CALL	CRLF
398	POP	HL
399PUTA1:	CALL	KI	     ;GET A CHARACTER
400	CP	4	     ;CONTROL-D? (EOT)
401	JP	Z,LFADR	     ;YES, STOP & PRINT
402	CP	'_'	     ;ERASE MISTAKE?
403	JR	Z,PUTA3	     ; YES.
404	LD	(HL),A	     ;ELSE STORE IT IN MEMORY
405	LD	C,A
406	INC	HL
407PUTA2:	CALL	CO	     ;ECHO ON CONSOLE
408	JR	PUTA1
409PUTA3:	DEC	HL
410	LD	C,(HL)
411	JR	PUTA2	     ;ECHO & CONTINUE
412;
413; THIS ROUTINE COMPARES THE READER INPUT
414; DEVICE WITH THE MEMORY BLOCK SPECIFIED.
415; IT TESTS ALL EIGHT BITS, AND ANY DISCREPENCIES
416; WILL BE OUTPUT TO THE CONSOLE. THIS IS USEFUL
417; WHEN USED WITH THE BINARY DUMP FORMAT TO BOTH
418; VERIFY PROPER READING & STORAGE, OR TO DETECT
419; PROGRAM CHANGES SINCE IT WAS LAST LOADED.
420;
421COMP:	CALL	EXLF	     ;GET START ' STOP ADDR.
422COM1:	CALL	RIFF	     ;GET A FULL READER BYTE
423	CP	(HL)	     ;8 BIT COMPARE
424	CALL	NZ,CERR	     ;CALL IF INVALID COMPARE
425	CALL	HILOX	     ;SEE IF RANGE SATISFIED
426	JR	COM1
427;
428; THIS SUBROUTINE IS USED TO DISPLAY THE
429; CURRENT LOCATION OF THE 'M' REGISTER POINTER (HL),
430; AND THE VALUE AT THE LOCATION, AND THE CONTENTS
431; OF THE ACCUMULATOR. USED BY TWO ROUTINES.
432;
433CERR:	LD	B,A	     ;SAVE ACC.
434	CALL	HLSP	     ;DISPLAY H&L
435	LD	A,(HL)
436	CALL	LBYTE	     ;PRINT 'M'
437	CALL	BLK	     ;SPACE OVER
438	LD	A,B
439	CALL	LBYTE	     ;PRINT ACC.
440	JP	CRLF	     ;CRLF & RETURN
441;
442; THIS DISPLAYS THE CONTENTS OF MEMORY IN BASE HEX
443; WITH THE STARTING LOCATION ON EACH LINE. (BETWEEN
444; THE TWO PARAMETERS GIVEN). 16 BYTES PER LINE MAX.
445;
446DISP:	CALL	EXLF	     ;GET DISPLAY RANGE
447DIS0:	CALL	LFADR	     ;CRLF & PRINT ADDR.
448DIS1:	CALL	BLK	     ;SPACE OVER
449	LD	A,(HL)
450	CALL	LBYTE
451	CALL	HILOX	     ;RANGE CHECK
452	LD	A,L
453	AND	0FH	     ;SEE IF TIME TO CRLF
454	JR	NZ,DIS1
455	JR	DIS0
456;
457; THIS OUTPUTS THE END OF FILE (EOF) PATTERN
458; FOR THE CHECKSUM LOADER.  IT IS USED AFTER
459; PUNCHING A BLOCK OF MEMORY WITH THE 'W'
460; COMMAND.  AN ADDRESS PARAMETER MAY BE GIVEN,
461; AND UPON READING, THIS ADDRESS WILL BE
462; AUTOMATICALLY PLACED IN THE 'P' COUNTER. THE
463; PROGRAM CAN THEN BE RUN WITH A SIMPLE 'G[CR]'
464; COMMAND.
465;
466EOF:	CALL	EXPR1	     ;GET OPTIONAL ADDR.
467	CALL	PEOL	     ;CRLF TO PUNCH
468	LD	C,':'	     ;FILE MARKER CUE
469	CALL	PUO
470	XOR	A	     ;ZERO LENGTH
471	CALL	PBYTE
472	POP	HL
473	CALL	PADR	     ;PUNCH OPTIONAL ADDR.
474	LD	HL,0	     ;FILE TYPE=0
475	CALL	PADR	     ;PUNCH IT
476	JP	NULL	     ;TRAILER & RETURN
477;
478; THIS COMMAND WILL FILL A BLOCK OF MEMORY
479; WITH A VALUE. IE: FO,1FFF,0 FILLS FROM
480; <1> TO <2> WITH THE BYTE <3>. HANDY FOR
481; INITIALIZING A BLOCK TO A SPECIFIC VALUE, OR
482; MEMORY TO A CONSTANT VALUE BEFOR LOADING
483; A PROGRAM.  (ZERO IS ESPECIALLY USEFUL.)
484;
485FILL:	CALL	EXPR3	     ;GET 3 PARAMETERS
486FI1:	LD	(HL),C	     ;STORE THE BYTE
487	CALL	HILO
488	JR	NC,FI1
489	POP	DE	     ;RESTORE STACK
490	JP	START	     ; IN CASE OF ACCIDENTS
491;
492; THIS COMMAND ALLOWS EXECUTION OF ANOTHER
493; PROGRAM WHILE RETAINING SOME MONITOR
494; CONTROL BY SETTING BREAKPOINTS.
495;
496; TO SIMPLY EXECUTE, TYPE 'G<ADDR>[CR]'. TO SET
497; A BREAKPOINT TRAP, ADD THE ADDRESS(ES) TO THE
498; COMMAND. IE: G<ADDR>,<BKPT>[CR]. TWO BREAKPOINTS
499; ARE ALLOWED, ENOUGH TO SATISFY MOST REQUIREMENTS.
500; ONCE A BREAKPOINT HAS BEEN REACHED, THE
501; REGISTERS MAY BE EXAMINED OR MODIFIED. THE
502; PROGRAM CAN THEN BE CONTINUED BY TYPING ONLY
503; A 'G[CR]'. OR ANOTHER BREAKPOINT COULD BE
504; IMPLEMENTED AT THAT TIME BY TYPING 'G,<BKPT>[CR]'.
505;
506; *NOTE: THIS IS SOFTWARE CONTROLLED, AND THE
507; BREAKPOINT MUST OCCUR ON AN INSTRUCTION
508; BYTE.
509;
510GOTO:	CALL	PCHK	     ;GET A POSSIBLE ADDRESS
511	JR	C,GOT3	     ;CR ENTERED
512	JR	Z,GOT0	     ;DELIMITER ENTERED
513	CALL	EXF	     ;GET ONE EXPRESSION
514	POP	DE
515	LD	HL,PLOC	     ;PLACE ADDRESS IN 'P' LOCATION
516	ADD	HL,SP
517	LD	(HL),D	     ;HIGH BYTE
518	DEC	HL
519	LD	(HL),E	     ;LOW BYTE
520	LD	A,B
521	CP	CR	     ;SEE IF LAST CHARACTER WAS A CR
522	JR	Z,GOT3	     ;YES, LEAVE
523GOT0:	LD	D,2	     ;TWO BREAKPOINTS MAX
524	LD	HL,TLOC	     ;POINT TO TRAP STORAGE
525	ADD	HL,SP
526GOT1:	PUSH	HL	     ;SAVE STORAGE POINTER
527	CALL	EXPR1	     ;GET A TRAP ADDRESS
528	LD	E,B	     ;SAVE DELIMITER
529	POP	BC	     ;TRAP ADDR.
530	POP	HL	     ;STORAGE
531	LD	A,B	     ;LOOK AT TRAP ADDR
532	OR	C
533	JR	Z,GOT2	     ;DON'T SET A TRAP AT 0
534	LD	(HL),C	     ;SAVE BKPT ADDR
535	INC	HL
536	LD	(HL),B
537	INC	HL
538	LD	A,(BC)	     ;PICK UP INST. BYTE
539	LD	(HL),A	     ;SAVE THAT TOO
540	INC	HL
541	LD	A,0FFH	     ;RST 7
542	LD	(BC),A	     ;SOFTWARE INTERUPT
543GOT2:	LD	A,E	     ;LOOK AT DELIMITER
544	CP	CR
545	JR	Z,GOT2A
546	DEC	D	     ;COUNT BKPTS
547	JR	NZ,GOT1	     ;GET ONE MORE
548GOT2A:	LD	A,0C3H	     ;SET UP JUMP INSTRUCTION
549	LD	(RST7),A     ; AT RESTART TRAP LOC.
550	LD	HL,TRAP	     ; TO MONITOR VECTOR
551	LD	(RST7+1),HL
552GOT3:	CALL	CRLF
553	POP	DE	     ;CLEAR SYSTEM RETURN
554	LD	HL,22	     ;FIND 'EXIT' ROUTINE
555	ADD	HL,SP	     ;UP IN STACK
556	JP	(HL)	     ;GO SOMPLACE
557;
558; THIS IS A 'QUICKIE' MEMORY TEST TO SPOT
559; HARD MEMORY FAILURES, OR ACCIDENTLY
560; PROTECTED MEMORY LOCATIONS. IT IS NOT
561; MEANT TO BE THE DEFINITIVE MEMORY DIAGNOSTIC.
562; IT IS, HOWEVER, NON-DESTRUCTIVE. ERRORS ARE
563; PRINTED ON THE CONSOLE AS FOLLOWS-
564; <ADDR> 00000100 WHERE <1> IS THE BAD BIT.
565; BIT LOCATION OF THE FAILURE IS EASILY
566; DETERMINED. NON-R/W MEMORY WILL RETURN
567; WITH- 11111111
568;
569TEST:	CALL	EXLF	     ;GET TWO PARAMS
570TEST1:	LD	A,(HL)	     ;READ A BYTE
571	LD	B,A	     ;SAVE IN B REG.
572	CPL
573	LD	(HL),A	     ;READ/COMPLIMENT/WRITE
574	XOR	(HL)	     ; & COMPARE
575	JR	Z,TEST2	     ;SKIP IF ZERO (OK)
576	PUSH	DE	     ;SAVE END POINTER
577	LD	D,B	     ;SAVE BYTE
578	LD	E,A	     ;SET-UP TO DISPLAY
579	CALL	HLSP	     ;PRINT BAD ADDR
580	CALL	BITS	     ;PRINT BAD BIT LOC.
581	CALL	CRLF
582	LD	B,D	     ;RESTORE BYTE
583	POP	DE	     ;RESTORE DE
584TEST2:	LD	(HL),B	     ;REPLACE BYTE
585	CALL	HILOX	     ;RANGE TEST
586	JR	TEST1
587;
588; THIS COMMAND MOVES MASS AMOUNTS OF MEMORY
589; FROM <1> THRU <2> TO THE ADDRESS STARTING
590; AT <3>.  THIS ROUTINE SHOULD BE USED WITH
591; SOME CAUTION, AS IT COULD SMASH MEMORY IF
592; CARLESSLY IMPLEMENTED.
593;
594;	M<1>,<2>,<3>
595;
596MOVE:	CALL	EXPR3	     ;GET 3 PARAMETERS
597MO1:	LD	A,(HL)	     ;PICK UP
598	LD	(BC),A	     ;PUT DOWN
599	INC	BC	     ;MOVE UP
600	CALL	HILOX	     ;CHECK IF DONE
601	JR	MO1
602;
603; THIS COMMAND READS THE CHECK-SUMMED HEX FILES
604; FOR BOTH THE NORMAL INTEL FORMAT AND THE TDL
605; RELOCATING FORMAT. ON BOTH FILES, A 'BIAS' MAY
606; BE ADDED, WHICH WILL CAUSE THE OBJECT CODE TO
607; BE PLACED IN A LOCATION OTHER THAN ITS
608; INTENDED EXECUTION LOCATION. THE BIAS IS ADDED
609; TO WHAT WOULD HAVE BEEN THE NORMAL LOADING
610; LOCATION, AND WILL WRAP AROUND TO ENABLE
611; LOADING ANY PROGRAM ANYWHERE IN MEMORY.
612;
613; WHEN LOADING A RELOCATABLE FILE, AN ADDITIONAL
614; PARAMETER MAY BE ADDED, WHICH REPRESENTS THE
615; ACTUAL EXECUTION ADDRESS DESIRED. THIS ALSO MAY
616; BE ANY LOCATION IN MEMORY.
617;
618; EXAMPLES:
619;
620; R[CR] =0 BIAS, 0 EXECUTION ADDR.
621; R<ADDR1>[CR] =<1>BIAS, 0 EXECUTION ADDR.
622; R,<ADDR1>[CR] =0 BIAS, <1> EXECUTION ADDR.
623; R<ADDR1>,<ADDR2>[CR] =<1>BIAS, <2>EXECUTION ADDR.
624;
625READ:	CALL	EXPR1	     ;GET BIAS, IF ANY
626	LD	A,B	     ;LOOK AT DELIMITER
627	SUB	CR	     ;ALL DONE?
628	LD	B,A	     ;SET UP RELOCATION OF 0
629	LD	C,A	     ; IF CR ENTERED
630	POP	DE	     ;BIAS AMOUNT
631	JR	Z,REA0	     ;CR ENTERED
632	CALL	EXPR1	     ;GET RELOCATION
633	POP	BC	     ;ACTUAL RELOCATION VALUE
634REA0:	EX	DE,HL
635	EXX		     ;HL'=BIAS, BC'=RELOCATION
636	CALL	CRLF
637LOD0:	CALL	RIX	     ;GET A CHARACTER
638	SUB	':'	     ;ABSOLUTE FILE CUE?
639	LD	B,A	     ;SAVE CUE CLUE
640	AND	0FEH	     ;KILL BIT 0
641	JR	NZ,LOD0	     ; NO, KEEP LOOKING
642	LD	D,A	     ;ZERO CHECKSUM
643	CALL	SBYTE	     ;GET FILE LENGTH
644	LD	E,A	     ;SAVE IN E REG.
645	CALL	SBYTE	     ;GET LOAD MSB
646	PUSH	AF	     ;SAVE IT
647	CALL	SBYTE	     ;GET LOAD LSB
648	EXX		     ;CHANGE GEARS
649	POP	DE	     ;RECOVER MSB
650	LD	E,A	     ;FULL LOAD ADDR
651	PUSH	BC	     ;BC'=RELOCATION
652	PUSH	DE	     ;DE'=LOAD ADDR
653	PUSH	HL	     ;HL'=BIAS
654	ADD	HL,DE	     ; BIAS+LOAD
655	EX	(SP),HL	     ;RESTORE HL'
656	POP	IX	     ; X=BIAS+LOAD
657	EXX		     ;DOWNSHIFT
658	POP	HL	     ;HL=LOAD ADDR
659	CALL	SBYTE	     ;GET FILE TYPE
660	DEC	A	     ;1=REL. FILE, 0=ABS.
661	LD	A,B	     ;SAVE CUE BIT
662	POP	BC	     ;BC=RELOCATION
663	JR	NZ,ABS0      ;ABSOLUTE FILE
664	ADD	HL,BC	     ;ELSE RELOCATE
665	ADD	IX,BC	     ;BOTH X & HL
666ABS0:	INC	E	     ;TEST LENGHT
667	DEC	E	     ;0=DONE
668	JR	Z,DONE
669	DEC	A	     ;TEST CUE
670	JR	Z,LODR	     ;RELATIVE
671LLO1:	CALL	SBYTE	     ;NEXT
672	CALL	STORE	     ;STORE IT
673	JR	NZ,LLO1	     ;MORE COMING
674LOD4:	CALL	SBYTE	     ;GET CHECKSUM
675	JR	Z,LOD0	     ;GOOD CHECKSUM
676ERR3:	PUSH	IX
677	POP	HL	     ;TRANSFER
678	CALL	LADR	     ;PRINT CURRENT LOAD ADDR
679ERR2:	JP	ERROR	     ;ABORT
680DONE:	LD	A,H	     ;DON'T MODIFY IF ZERO
681	OR	L
682	RET	Z
683	EX	DE,HL	     ;ELSE STORE IN PC
684	LD	HL,PLOC
685	ADD	HL,SP
686	LD	(HL),D	     ;IN STACK AREA
687	DEC	HL
688	LD	(HL),E
689	RET
690LODR:	LD	L,1	     ;SET-UP BIT COUNTER
691LOD1:	CALL	LODCB	     ;GET THE BIT
692	JR	C,LOD3	     ;DOUBLE BIT
693LOD5:	CALL	STORE	     ;WRITE IT
694	JR	NZ,LOD1
695	JR	LOD4	     ;TEST CHECKSUM
696LOD3:	LD	C,A	     ;SAVE LOW BYTE
697	CALL	LODCB	     ;NEXT CONTROL BIT
698	LD	B,A	     ;SAVE HIGH BYTE
699	EXX
700	PUSH	BC	     ;GET RELOCATION
701	EXX
702	EX	(SP),HL	     ;INTO HL
703	ADD	HL,BC	     ;RELOCATE
704	LD	A,L	     ;LOW BYTE
705	CALL	STORE	     ;STORE IT
706	LD	A,H	     ;HIGH BYTE
707	POP	HL	     ;RESTORE HL
708	JR	LOD5	     ;DO THIS AGAIN
709LODCB:	DEC	L	     ;COUNT BITS
710	JR	NZ,LC1	     ;MORE LEFT
711	CALL	SBYTE	     ;GET NEXT
712	DEC	E	     ;COUNT BYTES
713	LD	H,A	     ;SAVE THE BITS
714	LD	L,8	     ;8 BITS/BYTE
715LC1:	CALL	SBYTE	     ;GET A DATA BYTE
716	SLA	H	     ;TEST NEXT BIT
717	RET
718SBYTE:	PUSH	BC	     ;PRESERVE BC
719	CALL	RIBBLE	     ;GET A CONVERTED ASCII CHAR.
720	RLCA
721	RLCA
722	RLCA
723	RLCA		     ;MOVE IT TO HIGH NIBBLE
724	LD	C,A	     ;SAVE IT
725	CALL	RIBBLE	     ;GET OTHER HALF
726	OR	C	     ;MAKE WHOLE
727	LD	C,A	     ;SAVE AGAIN IN C
728	ADD	A,D	     ;UPDATE CHECKSUM
729	LD	D,A	     ;NEW CHECKSUM
730	LD	A,C	     ;CONVERTED BYTE
731	POP	BC
732	RET
733STORE:	LD	(IX+0),A     ;WRITE TO MEMORY
734	CP	(IX+0)	     ;VALID WRITE?
735	JR	NZ,ERR3	     ; NO.
736	INC	IX	     ;ADVANCE POINTER
737	DEC	E	     ;COUNT DOWN
738	RET
739;
740; THIS ROUTINE ALLOWS BOTH INSPECTION OF &
741; MODIFICATION OF MEMORY ON A BYTE BY BYTE
742; BASIS. IT TAKES ONE ADDRESS PARAMETER,
743; FOLLOWED BY A SPACE.  THE DATA AT THAT
744; LOCATION WILL BE DISPLAYED. IF IT IS
745; DESIRED TO CHANGE IT, THE VALUE IS THEN
746; ENTERED.  A FOLLOWING SPACE WILL DISPLAY
747; THE NEXT BYTE.  A CARRIAGE RETURN [CR]
748; WILL TERMINATE THE COMMAND.  THE SYSTEM
749; ADDS A CRLF AT LOCATIONS ENDING WITH EITHER
750; XXX0 OR XXX8. TO AID IN DETERMINING THE
751; PRESENT ADDRESS, IT IS PRINTED AFTER
752; EACH CRLF.  A BACKARROW [_] WILL BACK
753; UP THE POINTER AND DISPLAY THE
754; PREVIOUS LOCATION.
755;
756SUBS:	CALL	EXPR1	     ;GET STARTING ADDR
757	POP	HL
758SUB0:	LD	A,(HL)
759	CALL	LBYTE	     ;DISPLAY THE BYTE
760	CALL	COPCK	     ;MODIFY?
761	RET	C	     ; NO, ALL DONE
762	JR	Z,SUB1	     ;DON'T MODIFY
763	CP	05FH	     ;BACKUP?
764	JR	Z,SUB2
765	PUSH	HL	     ;SAVE POINTER
766	CALL	EXF	     ;GET NEW VALUE
767	POP	DE	     ;VALUE IN E
768	POP	HL
769	LD	(HL),E	     ;MODIFY
770	LD	A,B	     ;TEST DELIMITER
771	CP	CR
772	RET	Z	     ;DONE
773SUB1:	INC	HL
774SUB3:	LD	A,L	     ;SEE IF TIME TO CRLF
775	AND	7
776	CALL	Z,LFADR	     ;TIME TO CRLF
777	JR	SUB0
778SUB2:	DEC	HL	     ;DECREMENT POINTER
779	JR	SUB3	     ;AND PRINT DATA THERE.
780;
781; THIS ROUTINE TRANSLATES THE DATA IN
782; MEMORY TO AN ASCII FORMAT.  ALL NON-
783; PRINTING CHARACTERS ARE CONVERTED TO
784; PERIODS. [.]
785; THERE ARE 64 CHARACTERS PER LINE.
786;
787TYPE:	CALL	EXLF	     ;DISPLAY RANGE
788TYP0:	CALL	LFADR	     ;DISPLAY ADDRESS
789	LD	B,64	     ;CHARACTERS PER LINE
790TYP1:	LD	A,(HL)
791	AND	7FH	     ;KILL PARITY BIT
792	CP	' '	     ;RANGE TEST
793	JR	NC,TYP3	     ;=>SPACE
794TYP2:	LD	A,'.'	     ;REPLACE NON-PRINTING
795TYP3:	CP	07CH	     ;ABOVE LOWER CASE Z
796	JR	NC,TYP2
797	LD	C,A	     ;SEND IT
798	CALL	CO
799	CALL	HILOX	     ;MORE TO GO?
800	DJNZ	TYP1	     ;SEE IF TIME TO CRLF
801	JR	TYP0	     ;YES
802;
803; THIS IS A HEXADECIMAL SEARCH ROUTINE. IT
804; TAKES NO ADDRESS PARAMETERS. AS MANY
805; BYTES MAY BE ENTERED, SEPARATED BY A COMMA,
806; AS DESIRED.  THE MAXIMUM IS 255, BUT 3-4 IS
807; TYPICAL, AND MORE THAN 12 WOULD BE UNUSUAL.
808; THE ENTIRE MEMORY IS SEARCHED STARTING
809; FROM ZERO, AND ALL STARTING ADDRESSES OF EACH
810; OCCURANCE OF THE SEARCH STRING ARE PRINTED
811; ON THE CONSOLE DEVICE.
812;
813WHERE:	LD	D,0	     ;COUNT SEARCH STRING
814WHER0:	CALL	EXPR1	     ;GET ONE BYTE
815	POP	HL	     ;PICK IT UP
816	LD	H,L	     ;STICK IN HIGH BYTE
817	PUSH	HL	     ;PUT IT IN STACK
818	INC	SP	     ;ADJUST STACK
819	INC	D	     ;COUNT UP
820	LD	A,B	     ;TEST DELIMITER
821	SUB	CR
822	JR	NZ,WHER0     ;MORE TO GO
823	LD	B,A	     ;CHEAP ZEROS
824	LD	C,A
825	LD	H,A
826	LD	L,D	     ;GET BYTE COUNT IN L
827	DEC	L	     ;-1
828	ADD	HL,SP	     ;BYTES STORED IN STACK
829	PUSH	HL
830	PUSH	BC
831FINDC:	PUSH	BC	     ;SAVE THAT POINTER
832	CALL	CRLF
833	POP	BC	     ;RESTORE
834FIND:	POP	HL	     ;HL=SEARCH ADDR
835	POP	IX	     ;X=SEARCH BYTE POINTER
836	LD	E,D	     ;RESET COUNTER
837	LD	A,(IX+0)     ;GET THE FIRST SEARCH BYTE
838	CPIR		     ;COMPARE, INCR., & REPEAT
839	JP	PO,DONE	     ;ODD PARITY=DONE
840	PUSH	IX	     ;SAVE POINTERS
841	PUSH	HL
842FOUND:	DEC	E
843	JR	Z,TELL	     ;FOUND ALL
844	LD	A,(IX+-1)    ;LOOK AT NEXT MATCH
845	CP	(HL)	     ;TEST NEXT
846	JR	NZ,FIND	     ;NO MATCH
847	INC	HL	     ;BUMP POINTERS
848	DEC	IX
849	JR	FOUND	     ;TEST NEXT MATCH
850TELL:	POP	HL
851	PUSH	HL
852	DEC	HL
853	PUSH	BC	     ;SAVE SEARCH COUNT LIMIT
854	CALL	LADR	     ;TELL CONSOLE
855	POP	BC	     ;RESTORE
856	JR	FINDC
857DONE2:	INC	SP
858	DEC	E	     ;RESET STACK
859	JR	NZ,DONE2
860	RET
861;
862; THIS ROUTINE DUMPS MEMORY IN THE STANDARD
863; INTEL HEX-FILE FORMAT.  A START & END
864; PARAMETER IS REQUIRED. AT THE CONCLUSION
865; OF THE DUMP, AN "END OF FILE" SHOULD BE
866; GENERATED WITH THE "E" COMMAND.
867;
868WRITE:	CALL	EXLF	     ;GET TWO PARAMETERS
869	CALL	WAIT	     ;PAUSE IF TTY CONFIGURATION
870WRT0:	CALL	PEOL	     ;CRLF TO PUNCH
871	LD	BC,':'	     ;START OF FILE
872	CALL	PUO	     ;PUNCH IT
873	PUSH	DE	     ;SAVE
874	PUSH	HL	     ;POINTERS
875WRT1:	INC	B	     ;CALCULATE FILE LENGTH
876	CALL	HILO
877	JR	C,WRT4	     ;SHORT FILE
878	LD	A,24	     ;24 BYTES PER FILE
879	SUB	B	     ;ENOUGH YET?
880	JR	NZ,WRT1	     ; NO.
881	POP	HL	     ;GET START ADDR BACK.
882	CALL	WRT2	     ;SEND THE BLOCK
883	POP	DE	     ;RESTORE END OF FILE POINTER
884	JR	WRT0	     ;KEEP GOING
885WRT2:	LD	D,A	     ;INITIALIZE CHECKSUM
886	LD	A,B	     ;FILE LENGTH
887	CALL	PBYTE	     ;PUNCH IT
888	CALL	PADR	     ;PUNCH ADDRESS
889	XOR	A	     ;FILE TYPE=0
890	CALL	PBYTE	     ;PUNCH IT
891WRT3:	LD	A,(HL)	     ;GET A DATA BYTE
892	CALL	PBYTE	     ;PUNCH IT
893	INC	HL	     ;POINT TO NEXT BYTE
894	DJNZ	WRT3	     ;DECREMENT FILE COUNT
895	XOR	A
896	SUB	D	     ;CALCULATE CHECKSUM
897	JP	PBYTE	     ;PUNCH IT, RETURN
898WRT4:	POP	HL	     ;CLEAR STACK
899	POP	DE	     ; OF POINTERS
900	XOR	A	     ;SET UP A
901	JR	WRT2	     ;FINISH UP & RETURN
902;
903;
904;	THIS ROUTINE ALLOWS DISPLAYING THE
905; USER'S CPU REGISTERS. THEY ALSO MAY BE
906; USING THE REGISTER NAME AFTER TYPEING THE "X".
907; I.E. XA 00-
908; THE REGISTER MAY BE SKIPPED OVER, OR MODIFIED,
909; SIMILARLY TO THE "S" COMMAND.
910;
911; TO DISPLAY THE "NORMAL" SYSTEM STATUS,
912; SIMPLY TYPE "X[CR]".  TO DISPLAY THE
913; ADDITIONAL Z-80 REGISTERS, FOLLOW
914; THE "X" WITH AN APOSTROPHE.  I.E. "X'[CR]",
915; OR TO EXAMINE A SINGLE "PRIME" REGISTER,
916; TYPE THE REGISTER IDENTIFIER AFTER THE
917; APOSTROPHE.  I.E.  X'X 0000-
918;
919; THESE REGISTER VALUES ARE PLACED INTO THE CPU
920; UPON EXECUTING ANY "GO" COMMAND. [G]
921;
922XAM:	CALL	TI
923	LD	HL,ACTBL
924	CP	CR	     ;FULL REG. DISPLAY
925	JR	Z,XAM6
926	CP	27H	     ;SEE IF PRIMES WANTED
927	JR	NZ,XAM0
928	LD	HL,PRMTB
929	CALL	TI
930	CP	CR	     ;FULL REG. DISPLAY
931	JR	Z,XAM6
932XAM0:	CP	(HL)	     ;TEST FOR REGISTER NAME
933	JR	Z,XAM1
934	BIT	7,(HL)	     ;SEE IF END OF TABLE
935	JP	NZ,ERROR
936	INC	HL
937	INC	HL
938	JR	XAM0
939XAM1:	CALL	BLK
940XAM2:	INC	HL
941	LD	A,(HL)
942	LD	B,A	     ;SAVE FOR FLAGS
943	AND	3FH	     ;CLEAR FLAGS FOR BIAS
944	EX	DE,HL
945	LD	L,A	     ;DISPLACEMENT FROM STACK
946	LD	H,0
947	ADD	HL,SP
948	EX	DE,HL
949	INC	HL
950	LD	A,(DE)	     ;PICK UP REG. VALUE
951	CALL	LBYTE	     ;PRINT IT
952	BIT	7,B
953	JR	Z,XAM3
954	DEC	DE
955	LD	A,(DE)
956	CALL	LBYTE
957XAM3:	CALL	COPCK	     ;MODIFY
958	RET	C	     ;CR ENTERED, ALL DONE
959	JR	Z,XAM5	     ;SKIP TO NEXT REG.
960	PUSH	HL
961	PUSH	BC
962	CALL	EXF	     ;GET NEW VALUE
963	POP	HL
964	POP	AF
965	PUSH	BC
966	PUSH	AF
967	LD	A,L
968	LD	(DE),A
969	POP	BC
970	BIT	7,B	     ;SEE IF 8 BIT OR 16 BIT REG.
971	JR	Z,XAM4	     ;8 BIT
972	INC	DE
973	LD	A,H	     ;HIGH BYTE OF 16 BIT REG.
974	LD	(DE),A
975XAM4:	POP	BC
976	POP	HL
977	LD	A,B	     ;TEST DELIMITER
978	CP	CR
979	RET	Z	     ;CR ENTERED, ALL DONE
980XAM5:	BIT	7,(HL)	     ;SEE IF END OF TABLE
981	RET	NZ	     ;RETURN IF SO
982	JR	XAM2
983XAM6:	CALL	CRLF
984XAM7:	CALL	BLK
985	LD	A,(HL)
986	INC	HL
987	OR	A
988	RET	M
989	LD	C,A
990	CALL	CO
991	LD	C,'='
992	CALL	CO
993	LD	A,(HL)
994	LD	B,A	     ;SAVE FLAGS
995	AND	3FH	     ;CLEAR UP FOR OFFSET
996	INC	HL
997	EX	DE,HL
998	LD	L,A
999	LD	H,0
1000	ADD	HL,SP
1001	EX	DE,HL
1002	BIT	6,B	     ;TEST FOR SPECIAL "M"
1003	JR	NZ,XAM9	     ;PRINT OUT ACTUAL "M"
1004	LD	A,(DE)
1005	CALL	LBYTE	     ;PRINT REG. VALUE
1006	BIT	7,B	     ;SINGLE OR DOUBLE?
1007	JR	Z,XAM7	     ;SINGLE.
1008	DEC	DE
1009	LD	A,(DE)
1010XAM8:	CALL	LBYTE
1011	JR	XAM7
1012XAM9:	PUSH	HL	     ;SAVE HL
1013	LD	A,(DE)	     ;GET REG. POINTER
1014	LD	H,A	     ;HIGH BYTE
1015	DEC	DE
1016	LD	A,(DE)
1017	LD	L,A	     ;LOW BYTE
1018	LD	A,(HL)	     ;GET VALUE
1019	POP	HL	     ;RESTORE HL
1020	JR	XAM8	     ;PRINT VALUE & CONTINUE
1021;
1022; THIS IS A MESSAGE OUTPUT ROUTINE.
1023; IT IS USED BY THE SIGN-ON AND THE CRLF.
1024; POINTER IS IN HL (WHEN ENTERED AT
1025; TOM1) AND LENGTH IN B REG.
1026;
1027TOM:	LD	HL,MSG
1028TOM1:	LD	C,(HL)	     ;GET A CHARACTER
1029	INC	HL	     ;MOVE POINTER
1030	CALL	CO	     ;OUTPUT IT
1031	DJNZ	TOM1	     ;KEEP GOING TILL B=0
1032	CALL	CSTS	     ;SEE IF AN ABORT REQUEST
1033	OR	A	     ; WAITING
1034	RET	Z	     ;NO.
1035;
1036; SEE IF CONTROL-C IS WAITING
1037; ABORT IF SO.
1038;
1039CCHK:	CALL	KI
1040	CP	3	     ;CONTROL-C?
1041	RET	NZ
1042;
1043; SYSTEM ERROR ROUTINE. THIS
1044; WILL RESTORE THE SYTEM AFTER
1045; A SYSTEM ERROR HAS BEEN TAKEN.
1046; THE I/O CONFIGURATION IS NOT
1047; AFFECTED.
1048;
1049ERROR:	CALL	MEMSIZ
1050	LD	DE,-22	     ;STACK POINTER OFFSET
1051	ADD	HL,DE
1052	LD	SP,HL
1053	LD	C,'*'	     ;ANNOUNCE ERROR
1054	CALL	CO
1055	JP	START	     ;BACK TO WORK
1056;
1057; THIS GETS A READER CHARACTER,
1058; AND COMPARES IT WITH THE 'D' REG.
1059; IT ABORTS ON AN 'OUT-OF-DATA'
1060; CONDITION.
1061;
1062RIFF:	CALL	RI	     ;GET READER CHARACTER
1063	JR	C,ERROR	     ;ABORT ON CARRY
1064	CP	D	     ;TEST D
1065	RET
1066;
1067; THIS ROUTINE WILL RETURN THE
1068; CURRENT VALUE OF THE HIGHEST
1069; READ/WRITE MEMORY LOCATION THAT
1070; IS AVAILABLE ON THE SYSTEM.
1071; IT WILL "SEARCH" FOR MEMORY
1072; STARTING AT THE BOTTOM OF MEMORY
1073; AND GO UPWARDS UNTIL NON-R/W MEMORY
1074; IS FOUND.
1075;
1076SIZE:	CALL	MEMSIZ	     ;GET THE VALUE
1077	LD	BC,ENDX-EXIT
1078	ADD	HL,BC	     ;ADJUST IT
1079;
1080;
1081; CRLF BEFORE HLSP ROUTINE
1082;
1083LFADR:	CALL	CRLF
1084;
1085; PRINT THE CURRENT VALUE OF H&L,
1086; AND A SPACE.
1087;
1088HLSP:	CALL	LADR
1089;
1090; PRINT A SPACE ON THE CONSOLE
1091;
1092BLK:	LD	C,' '
1093;
1094; THIS IS THE MAIN CONSOLE
1095; OUTPUT ROUTINE
1096;
1097CO:	CALL	IOCHK
1098	AND	~CMSK
1099	JR	NZ,CO0
1100;
1101; TELEPRINTER CONFIGURATION
1102; I/O DRIVER.
1103;
1104TTYOUT:	IN	A,(TTS)
1105	AND	TTYBE
1106	JR	Z,TTYOUT
1107	LD	A,C
1108	OUT	(TTO),A
1109	RET
1110CO0:	DEC	A	     ;CCRT?
1111	JR	NZ,CO1	     ; NO.
1112;
1113; C.R.T. CONFIGURATION DRIVER.
1114;
1115CRTOUT:	IN	A,(CRTS)
1116	AND	CRTBE
1117	JR	NZ,CRTOUT
1118	LD	A,C
1119	OUT	(CRTO),A
1120	RET
1121;
1122CO1:	DEC	A	     ;BATCH
1123	JP	NZ,COLOC     ; NO, MUST BE USER
1124;
1125; LIST OUTPUT DRIVER ROUTINE
1126; -A USER VECTORED ROUTINE, USED
1127; BY THE ASSEMBLER, ETC. ALSO,
1128; WHEN THE ASSIGNED MODE IS "BATCH",
1129; THIS IS THE ROUTINE USED FOR THE
1130; MONITOR OUTPUT THAT WOULD NORMALLY
1131; GO TO THE "CONSOLE".
1132;
1133LO:	CALL	IOCHK
1134	AND	~LMSK
1135	JR	Z,TTYOUT
1136	CP	LCRT
1137	JR	Z,CRTOUT
1138	CP	LINE
1139	JP	Z,LNLOC	     ;EXTERNAL VECTOR
1140	JP	LULOC	     ;USER DEFINED VECTOR
1141;
1142; SEND CRLF TO PUNCH DEVICE
1143;
1144PEOL:	LD	C,CR
1145	CALL	PUO
1146	LD	C,LF
1147;
1148; PUNCH OUTPUT DRIVER ROUTINE
1149;
1150PUO:	CALL	IOCHK
1151	AND	~PMSK
1152	JR	Z,TTYOUT     ;PUNCH=TELEPRINTER
1153	CP	PCAS	     ;CASSETTE?
1154	JR	NZ,PO1	     ; NO.
1155;
1156PO0:	IN	A,(PCASS)    ;CASSETTE DRIVER
1157	AND	PCSBE
1158	JR	NZ,PO0
1159	LD	A,C
1160	OUT	(PCASO),A
1161	RET
1162;
1163PO1:	CP	PPTP
1164	JP	Z,PTPL	     ;EXTERNAL VECTOR
1165	JP	PULOC	     ;USER VECTOR
1166;
1167;
1168; THIS IS A BINARY DUMP ROUTINE THAT MAY BE
1169; USED WITH BOTH PAPER-TAPE AND/OR CASSETTE
1170; SYSTEMS.  IT PUNCHES A START-OF-FILE MARK
1171; AND THEN PUNCHES IN FULL 8-BITS DIRECTLY
1172; FROM MEMORY.  IT IS FOLLOWED BY AN END-OF-
1173; FILE MARKER. THESE DUMPS MAY BE LOADED
1174; USING THE "L" COMMAND. THEY ARE USEFUL
1175; FOR FAST LOADING, AND MAY BE VERIFIED
1176; USING THE "C" (COMPARE) COMMAND.
1177;
1178; U<A1>,<A2>[CR]
1179; PUNCHES FROM <A1> THRU <A2>
1180;
1181UNLD:	CALL	EXLF	     ;GET TWO PARAMETERS
1182	CALL	WAIT	     ;PAUSE FOR PUNCH-ON (TTY)
1183	CALL	LEAD	     ;PUNCH LEADER
1184	CALL	MARK	     ;PUNCH FILE MARKER
1185UNL:	LD	C,(HL)	     ;GET MEMORY BYTE
1186	CALL	PUO	     ;PUNCH IT
1187	CALL	HILO	     ;SEE IF DONE
1188	JR	NC,UNL
1189	CALL	MARK	     ;PUNCH END OF FILE MARKER
1190;
1191; THIS PUNCHES NULLS (LEADER/TRAILER).
1192; IT RETURNS "QUIET" IN CASE THE PUNCH
1193; AND CONSOLE ARE THE SAME.
1194;
1195NULL:	CALL	LEAD	     ;PUNCH NULLS
1196;
1197; THIS ROUTINE WILL PAUSE FOR
1198; A KEYBOARD CHARACTER. IT IS
1199; USED AS A DELAY TO GIVE THE
1200; OPERATOR TIME TO TURN ON THE
1201; TELEPRINTER PUNCH BEFORE SENDING
1202; A HEX FILE OR BINARY FILE TO
1203; THE PUNCH.  IT WILL SIMPLY
1204; RETURN IF THE PUNCH & CONSOLE
1205; ARE NOT BOTH ASSIGNED TO THE
1206; DEFAULT. (TELEPRINTER)
1207;
1208WAIT:	CALL	IOCHK
1209	AND	~CMSK | ~PMSK
1210	RET	NZ
1211	JP	STARO	     ;RETURN "QUIET"
1212;
1213; CONVERT HEX TO ASCII
1214;
1215CONV:	AND	0FH	     ;LOW NIBBLE ONLY
1216	ADD	A,90H
1217	DAA
1218	ADC	A,40H
1219	DAA
1220	LD	C,A
1221	RET
1222;
1223; GET TWO PARAMETERS, PLACE
1224; THEM IN DE & HL, AND THEN
1225; CRLF.
1226;
1227EXLF:	CALL	EXPR
1228	POP	DE
1229	POP	HL
1230;
1231; CONSOLE CARRIAGE RETURN &
1232; LINE FEED ROUTINE.
1233;
1234; THE NUMBER OF FILL CHARACTERS
1235; MAY BE ADJUSTED TO 0-3 BY THE
1236; VALUE PLACED IN THE B REG. MINIMUM
1237; VALUE FOR "B" IS TWO (2). MAXIMUM
1238; IS FIVE (5).
1239;
1240CRLF:	PUSH	HL	     ;SAVE HL
1241	LD	B,4	     ;CRLF LENGTH (SET FOR 2 FILLS)
1242	CALL	TOM	     ;SEND CRLF
1243	POP	HL
1244	RET
1245;
1246; TEST THE CURRENT CONSOLES
1247; KEYBOARD FOR A KEY-PRESS.
1248; RETURN TRUE (0FFH IN A REG)
1249; IF THERE IS A CHARACTER
1250; WAITING IN THE UART.
1251;
1252CSTS:	CALL	IOCHK
1253	AND	~CMSK
1254	JR	NZ,CS0
1255	IN	A,(TTS)
1256	JR	CS1
1257CS0:	DEC	A	     ;CCRT
1258	JR	NZ,CS3
1259	IN	A,(CRTS)
1260CS1:	AND	TTYDA
1261	LD	A,FALSE
1262CS2:	RET	Z
1263	CPL
1264	RET
1265CS3:	DEC	A	     ;BATCH
1266	RET	Z
1267	JP	CSLOC	     ;USER DEFINED FUNCTION
1268;
1269; GET THREE PARAMETERS AND
1270; CRLF.
1271;
1272EXPR3:	INC	C
1273	CALL	EXPR
1274	CALL	CRLF
1275	POP	BC
1276	POP	DE
1277	POP	HL
1278	RET
1279;
1280; GET ONE PARAMETER.
1281; NO CRLF.
1282;
1283EXPR1:	LD	C,1
1284;
1285; THIS IS THE MAIN "PARAMETER-GETTING" ROUTINE.
1286; THIS ROUTINE WILL ABORT ON A NON-HEX CHARACTER.
1287; IT TAKES THE MOST RECENTELY TYPED FOUR VALID
1288; HEX CHARACTERS, AND PLACES THEM UP ON THE STACK.
1289; (AS ONE 16 BIT VALUE, CONTAINED IN TWO
1290; 8-BIT BYTES.)  IF A CARRIAGE RETURN IS ENTERED,
1291; IT WILL PLACE THE VALUE OF "0000" IN THE STACK.
1292;
1293EXPR:	LD	HL,0	     ;INITIALIZE HL TO ZERO
1294EX0:	CALL	TI	     ;GET SOMETHING FROM CONSOLE
1295EX1:	LD	B,A	     ;SAVE IT
1296	CALL	NIBBLE	     ;CONVERT ASCII TO HEX
1297	JR	C,EX2	     ;ILLEGAL CHARACTER DECTECTED
1298	ADD	HL,HL	     ;MULTIPLY BY 16
1299	ADD	HL,HL
1300	ADD	HL,HL
1301	ADD	HL,HL
1302	OR	L	     ;OR IN THE SINGLE NIBBLE
1303	LD	L,A
1304	JR	EX0	     ;GET SOME MORE
1305EX2:	EX	(SP),HL	     ;SAVE UP IN STACK
1306	PUSH	HL	     ;REPLACE THE RETURN
1307	LD	A,B	     ;TEST THE DELIMITER
1308	CALL	QCHK
1309	JR	NC,EX3	     ;CR ENTERED
1310	DEC	C	     ;SHOULD GO TO ZERO
1311	RET	Z	     ; RETURN IF IT DOES
1312EX3:	JP	NZ,ERROR     ;SOMETHING WRONG
1313	DEC	C	     ;DO THIS AGAIN?
1314	JR	NZ,EXPR	     ; YES.
1315	RET		     ;ELSE RETURN
1316EXF:	LD	C,1
1317	LD	HL,0
1318	JR	EX1
1319;
1320; RANGE TESTING ROUTINES.
1321; CARRY SET INDICATES RANGE EXCEEDED.
1322;
1323HILOX:	CALL	HILO
1324	RET	NC	     ;OK
1325	POP	DE	     ;RETURN ONE LEVEL BACK
1326	RET
1327;
1328HILO:	INC	HL	     ;INCREMENT HL
1329	LD	A,H	     ;TEST FOR CROSSING 64K BORDER
1330	OR	L
1331	SCF		     ;CARRY SET=STOP
1332	RET	Z	     ;YES, BORDER CROSSED
1333	LD	A,E	     ;NOW, TEST HL VS. DE
1334	SUB	L
1335	LD	A,D
1336	SBC	A,H
1337	RET		     ;IF CARRY WAS SET, THEN STOP
1338;
1339;	HEXADECIMAL MATH ROUTINE
1340;
1341; THIS ROUTINE IS USEFUL FOR
1342; DETERMINING RELATIVE JUMP
1343; OFFSETS.  IT RETURNS THE SUM
1344; & DIFFERENCE OF TWO PARAMETERS.
1345;
1346;  H<X>,<Y>
1347;
1348; X+Y   X-Y
1349;
1350HEXN:	CALL	EXLF
1351	PUSH	HL	     ;SAVE HL FOR LATER
1352	ADD	HL,DE	     ;GET SUM
1353	CALL	HLSP	     ;PRINT IT
1354	POP	HL	     ;THIS IS LATER
1355	OR	A	     ;CLEAR CARRY
1356	SBC	HL,DE	     ;GET DIFFERENCE & PRINT IT
1357;
1358; PRINT H&L ON CONSOLE
1359;
1360LADR:	LD	A,H
1361	CALL	LBYTE
1362	LD	A,L
1363LBYTE:	PUSH	AF
1364	RRCA
1365	RRCA
1366	RRCA
1367	RRCA
1368	CALL	LAD
1369	POP	AF
1370LAD:	CALL	CONV
1371	JP	CO
1372; THIS ROUTINE SENDS EIGHT RUBOUTS
1373; TO THE PUNCH DEVICE.
1374;
1375MARK:	LD	BC,08FFH     ;SET-UP B&C
1376	JR	LE0
1377;
1378; THIS ROUTINE SENDS BLANKS TO THE
1379; PUNCH DEVICE.
1380;
1381LEAD:	LD	BC,4800H     ;PRESET SOME NULLS
1382LE0:	CALL	PUO
1383	DJNZ	LE0
1384	RET
1385;
1386; THIS ROUTINE RETURNS TO A USER
1387; PROGRAM THE CURRENT TOP OF
1388; MEMORY VALUE MINUS WORKSPACE
1389; AREA USED BY THE MONITOR.
1390;
1391MEMCK:	PUSH	HL
1392	CALL	MEMSIZ
1393	LD	A,L
1394	SUB	2CH
1395	JR	NC,MEMC
1396	DEC	H
1397MEMC:	LD	B,H
1398	POP	HL
1399	RET
1400;
1401; THIS IS A CALLED ROUTINE USED
1402; TO CALCULATE THE TOP OF MEMORY
1403; STARTING FROM THE BOTTOM OF
1404; MEMORY, AND SEARCHING UPWARD UNTIL
1405; FIRST R/W MEMORY IS FOUND, AND THEN
1406; CONTINUING UNTIL THE END OF THE R/W
1407; MEMORY. THIS ALLOWS R.O.M. AT ZERO,
1408; AND INSURES A CONTINUOUS MEMORY BLOCK
1409; HAS BEEN FOUND.
1410; IT IS USED BY THE ERROR ROUTINE TO
1411; RESET THE STACK POINTER AS WELL.
1412;
1413MEMSIZ:	PUSH	BC
1414	LD	BC,BASE	     ;POINT TO START OF MONITOR
1415	LD	HL,-1	     ;RAM SEARCH STARTING PT.
1416MEM0:	INC	H	     ;FIRST FIND R/W MEMORY
1417	LD	A,(HL)
1418	CPL
1419	LD	(HL),A
1420	CP	(HL)
1421	CPL
1422	LD	(HL),A
1423	JR	NZ,MEM0
1424MEM1:	INC	H	     ;R/W FOUND, NOW FIND END
1425	LD	A,(HL)
1426	CPL
1427	LD	(HL),A
1428	CP	(HL)
1429	CPL
1430	LD	(HL),A
1431	JR	NZ,MEM2
1432	LD	A,H	     ;TEST FOR MONITOR BORDER
1433	CP	B
1434	JR	NZ,MEM1	     ;NOT THERE YET
1435MEM2:	DEC	H	     ;BACK UP, SUBTRACT WORKSPACE
1436	LD	BC,EXIT-ENDX
1437	ADD	HL,BC
1438	POP	BC	     ;RESTORE BC
1439	RET		     ;VALUE IN HL
1440;
1441;
1442RIBBLE:	CALL	RIX
1443NIBBLE:	SUB	'0'	     ;QUALIFY & CONVERT
1444	RET	C	     ;<0
1445	CP	'G'-'0'	     ;>F?
1446	CCF		     ;PERVERT CARRY
1447	RET	C
1448	CP	10	     ;NMBR?
1449	CCF		     ;PERVERT AGAIN
1450	RET	NC	     ;RETURN CLEAN
1451	SUB	'A'-'9'-1    ;ADJUST
1452	CP	0AH	     ;FILTER ":" THRU "@"
1453	RET
1454;
1455; SEND H&L VALUE TO PUNCH DEVICE
1456;
1457PADR:	LD	A,H
1458	CALL	PBYTE
1459	LD	A,L
1460;
1461; PUNCH A SINGLE BYTE
1462;
1463PBYTE:	PUSH	AF	     ;NIBBLE AT A TIME
1464	RRCA
1465	RRCA
1466	RRCA
1467	RRCA
1468	CALL	CONV
1469	CALL	PUO
1470	POP	AF	     ;NEXT NIBBLE
1471	PUSH	AF	     ;SAVE FOR CHECKSUM
1472	CALL	CONV
1473	CALL	PUO
1474	POP	AF	     ;ORIGINAL BYTE HERE
1475	ADD	A,D	     ;ADDED TO CHECKSUM
1476	LD	D,A	     ;UPDATE CHECKSUM
1477	RET
1478;
1479;
1480COPCK:	LD	C,'-'	     ;PROMPT FOR CONSOLE
1481	CALL	CO
1482;
1483PCHK:	CALL	TI
1484;
1485; TEST FOR DELIMITERS
1486;
1487QCHK:	CP	' '	     ;RETURN ZERO IF DELIMITER
1488	RET	Z
1489	CP	','
1490	RET	Z
1491	CP	CR	     ;RETURN W/CARRY SET IF CR
1492	SCF
1493	RET	Z
1494	CCF		     ;ELSE NON-ZERO, NO CARRY
1495	RET
1496;
1497; MAIN CONSOLE INPUT ROUTINE
1498;
1499CI:	CALL	IOCHK
1500	AND	~CMSK
1501	JR	NZ,CI1
1502;
1503; TELEPRINTER ROUTINE
1504;
1505TTYIN:	IN	A,(TTS)
1506	AND	TTYDA
1507	JR	Z,TTYIN
1508	IN	A,(TTI)
1509	RET
1510;
1511CI1:	DEC	A	     ;CONSOLE=CRT?
1512	JR	NZ,CI2
1513;
1514; C.R.T. INPUT ROUTINE
1515;
1516CRTIN:	IN	A,(CRTS)
1517	AND	CRTDA
1518	JR	Z,CRTIN
1519	IN	A,(CRTI)
1520	RET
1521;
1522CI2:	DEC	A	     ;BATCH?
1523	JP	NZ,CILOC     ;NO, MUST BE USER DEFINED
1524;
1525;
1526; READER INPUT ROUTINE, WITH
1527; TIME-OUT DELAY. INCLUDES
1528; PULSING OF HARDWARE PORT
1529; TO INDICATE REQUEST FOR
1530; READER DATA.
1531;
1532RI:	PUSH	HL
1533	CALL	IOCHK
1534	AND	~RMSK
1535;	CPL
1536;	OUT	(RCP),A	     ;PULSE READER CONTROL PORT
1537;	CPL		     ;CLEAR IT
1538;	OUT	(RCP),A
1539	JR	NZ,RI3	     ;NOT TTY
1540	LD	H,A	     ;CLEAR FOR-TIME OUT TEST
1541RI0:	IN	A,(TTS)
1542	AND	TTYDA
1543	JR	NZ,RI2
1544	PUSH	BC
1545	LD	B,0
1546DL0:	EX	(SP),HL	     ;WASTE TIME
1547	EX	(SP),HL	     ;FOR DELAY
1548	DJNZ	DL0
1549	POP	BC
1550	DEC	H
1551	JR	NZ,RI0
1552RI1:	XOR	A
1553	SCF
1554	POP	HL
1555	RET
1556RI2:	IN	A,(TTI)
1557RID:	OR	A
1558	POP	HL
1559	RET
1560RI3:	CP	RCAS
1561	JR	NZ,RI6
1562	IN	A,(SWITCH)   ;READ INITIAL SENSE CONDX.
1563	LD	L,A
1564RI4:	IN	A,(SWITCH)   ;SEE IF SW. ALTERED
1565	CP	L
1566	JR	NZ,RI1	     ;ABORT IF SO
1567	IN	A,(RCSS)     ;CASSETTE INPUT DRIVER
1568	AND	RCSDA	     ;DATA YET?
1569	JR	NZ,RI4	     ;KEEP LOOKING
1570RI5:	IN	A,(RCSD)
1571	JR	RID
1572RI6:	POP	HL
1573	CP	RPTR
1574	JP	Z,RPTPL	     ;EXTERNAL ROUTINE
1575	JP	RULOC	     ;USER VECTOR
1576;
1577; THIS ROUTINE GETS READER INPUT
1578; AND KILLS THE PARITY BIT.
1579;
1580RIX:	CALL	RIFF
1581	AND	7FH
1582	RET
1583;
1584; THIS ROUTINE READS A BINARY FILE
1585; IMAGE, IN THE FORM AS PUNCHED IN
1586; THE "U" (UNLOAD) COMMAND.  IT TAKES
1587; ONE PARAMETER, WHICH IS THE STARTING
1588; ADDRESS OF THE LOAD, AND WILL PRINT
1589; THE LAST ADDRESS (+1) LOADED ON THE
1590; CONSOLE DEVICE.
1591;
1592LOAD:	CALL	EXPR1	     ;INITIAL LOAD ADDRESS
1593	POP	HL
1594	CALL	CRLF
1595	LD	D,0FFH	     ;START-OF-FILE TAG
1596LOAD0:	LD	B,4	     ;FIND AT LEAST FOUR 0FFH'S
1597LOAD1:	CALL	RIFF
1598	JR	NZ,LOAD0
1599	DJNZ	LOAD1
1600LOAD2:	CALL	RIFF	     ;4 FOUND, NOW WAIT FOR NON-0FFH
1601	JR	Z,LOAD2
1602	LD	(HL),A	     ;FIRST REAL DATA BYTE
1603	LD	A,BELL	     ;TELL TTY
1604	OUT	(TTO),A
1605LOAD3:	INC	HL
1606	CALL	RIFF
1607	JR	Z,ELOA	     ;POSSIBLE END OF FILE
1608	LD	(HL),A
1609	JR	LOAD3
1610ELOA:	LD	E,1	     ;INITIALIZE
1611ELOA0:	CALL	RIFF
1612	JR	NZ,ELOA1
1613	INC	E	     ;COUNT QUES
1614	LD	A,MAX	     ;LOOK FOR EOF
1615	CP	E	     ;FOUND MAX?
1616	JR	NZ,ELOA0     ;NOPE
1617	JP	LADR	     ;YEP, PRINT END ADDR
1618ELOA1:	LD	(HL),D
1619	INC	HL
1620	DEC	E	     ;RESTORE
1621	JR	NZ,ELOA1
1622	LD	(HL),A	     ;REAL BYTE
1623	JR	LOAD3
1624;
1625; THIS IS THE BREAKPOINT "TRAP" HANDLING
1626; ROUTINE.  ALL USER REGISTERS ARE SAVED
1627; FOR DISPLAY PURPOSES, AND THE CONTENTS
1628; ARE RESTORED WHEN EXECUTING A "GO" (G)
1629; COMMAND.
1630;
1631RESTART:
1632	PUSH	HL	     ;PUSH ALL REGISTERS
1633	PUSH	DE
1634	PUSH	BC
1635	PUSH	AF
1636	CALL	MEMSIZ	     ;GET MONITOR'S STACK VALUE
1637	EX	DE,HL
1638	LD	HL,10	     ;GO UP 10 BYTES IN STACK
1639	ADD	HL,SP
1640	LD	B,4	     ;PICK OFF REG.
1641	EX	DE,HL
1642RES0:	DEC	HL
1643	LD	(HL),D	     ;SAVE IN WORKAREA
1644	DEC	HL
1645	LD	(HL),E
1646	POP	DE
1647	DJNZ	RES0
1648	POP	BC
1649	DEC	BC	     ;ADJUST P.C. VALUE
1650	LD	SP,HL	     ;SET MONITOR STACK
1651	LD	HL,TLOCX
1652	ADD	HL,SP
1653	LD	A,(HL)
1654	SUB	C	     ;LOOK FOR A TRAP/MATCH
1655	INC	HL
1656	JR	NZ,RES1
1657	LD	A,(HL)
1658	SUB	B
1659	JR	Z,RES3	     ;NO TRAP HERE
1660RES1:	INC	HL
1661	INC	HL
1662	LD	A,(HL)
1663	SUB	C	     ;TEST FOR SECOND TRAP
1664	JR	NZ,RES2
1665	INC	HL
1666	LD	A,(HL)
1667	SUB	B
1668	JR	Z,RES3
1669RES2:	INC	BC	     ;NO TRAPS SET, RE-ADJUST P.C.
1670RES3:	LD	HL,LLOCX
1671	ADD	HL,SP
1672	LD	(HL),E	     ;STORE USER H&L
1673	INC	HL
1674	LD	(HL),D
1675	INC	HL
1676	INC	HL
1677	LD	(HL),C	     ;AND USER P.C.
1678	INC	HL
1679	LD	(HL),B
1680	PUSH	BC
1681	LD	C,'@'	     ;DISPLAY BREAK ADDRESS.
1682	CALL	CO
1683	POP	HL
1684	CALL	LADR
1685	LD	HL,TLOCX
1686	ADD	HL,SP
1687	LD	BC,200H
1688RES4:	LD	E,(HL)	     ;REPLACE BYTES TAKEN FOR TRAP
1689	LD	(HL),C	     ;ZERO OUT STORAGE AREA
1690	INC	HL
1691	LD	D,(HL)
1692	LD	(HL),C
1693	INC	HL
1694	LD	A,E
1695	OR	D	     ;DO NOTHING IF ZERO
1696	JR	Z,RES5
1697	LD	A,(HL)
1698	LD	(DE),A	     ;STORE BYTE
1699RES5:	INC	HL	     ;SAME THING
1700	DJNZ	RES4	     ;FOR OTHER BREAKPOINT
1701	EX	AF,AF'	     ;GET ALTERNATE SET OF REG.'S
1702	EXX
1703	PUSH	HL	     ;AND STORE IN WORKSPACE
1704	PUSH	DE
1705	PUSH	BC
1706	PUSH	AF
1707	PUSH	IX
1708	PUSH	IY
1709	LD	A,I	     ;GET INTERUPT VECTOR BYTE
1710	LD	B,A
1711	LD	A,R	     ;GET REFRESH BYTE
1712	LD	C,A
1713	PUSH	BC	     ;SAVE
1714	JP	START	     ;BACK TO START
1715;
1716; THIS IS THE INTERNAL KEYBOARD
1717; HANDLING ROUTINE. IT WILL IGNORE
1718; RUBOUTS (0FFH) AND BLANKS (00),
1719; AND IT WILL NOT ECHO CR'S & N'S.
1720; (NO N'S FOR THE "NULL" COMMAND).
1721; IT CONVERTS LOWER CASE TO UPPER
1722; CASE FOR THE LOOK-UP OF COMMANDS.
1723;
1724; OTHER CHARACTERS ARE ECHOED AS THEY
1725; ARE RECEIVED.
1726;
1727KI:	CALL	CI	     ;GET CHARACTER FROM CONSOLE
1728	AND	7FH	     ;CLEAR PARITY BIT
1729	RET
1730;
1731TI:	CALL	KI
1732	INC	A	     ;IGNORE RUBOUTS
1733	RET	M
1734	DEC	A	     ;IGNORE NULLS
1735	RET	Z
1736	CP	'N'	     ;IGNORE N'S FOR NULL CMND
1737	RET	Z
1738	CP	'n'
1739	JR	Z,TI0
1740	CP	CR	     ;IGNORE CR'S
1741	RET	Z
1742	PUSH	BC
1743	LD	C,A
1744	CALL	CO
1745	LD	A,C
1746	POP	BC
1747	CP	'A'-1	     ;CONVERT TO UPPER CASE
1748	RET	C
1749	CP	'z'+1
1750	RET	NC
1751TI0:	AND	05FH
1752	RET
1753;
1754; THIS ROUTINE ALLOWS EXAMINATION OF
1755; ANY INPUT PORT, OR THE SENDING OF
1756; ANY VALUE TO ANY PORT.
1757;
1758; QO<N>,<V>[CR]
1759;	OUTPUT TO PORT <N>, THE VALUE <V>
1760;
1761; QI<N>[CR]
1762;	DISPLAY THE PORT <N>
1763;
1764QUERY:	CALL	TI
1765	CP	'O'
1766	JR	Z,QUO
1767	CP	'I'
1768	JP	NZ,ERROR
1769	CALL	EXPR1
1770	POP	BC
1771	IN	E,(C)
1772BITS:	LD	B,8	     ;DISPLAY 8 BITS
1773	CALL	BLK
1774QUE2:	SLA	E
1775	LD	A,'0'>1
1776	ADC	A,A	     ;MAKE "0" OR "1"
1777	LD	C,A
1778	CALL	CO
1779	DJNZ	QUE2
1780	RET
1781QUO:	CALL	EXPR
1782	POP	DE
1783	POP	BC
1784	OUT	(C),E
1785	RET
1786;
1787; THIS ROUTINE VERIFIES THE CONTENTS
1788; OF ONE MEMORY BLOCK WITH ANOTHER.
1789;
1790; V<ADDR1>,<ADDR2>,<ADDR3>
1791;	VERIFY FROM <1> THRU <2> WITH
1792; THE CONTENTS OF MEMORY BEGINNING AT <3>
1793;
1794VERIFY:	CALL	EXPR3	     ;GET 3 PARAMETERS
1795VERI0:	LD	A,(BC)
1796	CP	(HL)
1797	JR	Z,VERI1
1798	PUSH	BC
1799	CALL	CERR	     ;DISPLAY ERRORS
1800	POP	BC
1801VERI1:	INC	BC
1802	CALL	HILOX
1803	JR	VERI0
1804;
1805; <SYSTEM I/O LOOK-UP TABLE>
1806;
1807; THE FIRST CHARACTER IS THE DEVICE NAME
1808; (ONE LETTER) AND THE NEXT FOUR ARE THE
1809; NAMES OF THE FOUR POSSIBLE DRIVERS TO BE
1810; ASSIGNED.
1811;
1812LTBL:
1813	DEFB	'C'	     ;CONSOLE ASSIGNMENTS
1814	DEFB	'T'	     ;CTTY	T=TELEPRINTER
1815	DEFB	'C'	     ;CCRT	C=CRT (VIDEO MONITOR)
1816	DEFB	'B'	     ;BATCH= COMMANDS FROM READER
1817	DEFB	'U'	     ;CUSE	USER
1818;
1819	DEFB	'R'	     ;READER ASSIGNMENTS
1820	DEFB	'T'	     ;RTTY
1821	DEFB	'P'	     ;RPTR	P=PAPER TAPE
1822	DEFB	'C'	     ;RCAS	C=CASSETTE
1823	DEFB	'U'	     ;RUSER	USER
1824;
1825	DEFB	'P'	     ;PUNCH ASSIGNMENTS
1826	DEFB	'T'	     ;PTTY
1827	DEFB	'P'	     ;PPTP
1828	DEFB	'C'	     ;PCAS	C=CASSETTE
1829	DEFB	'U'	     ;PUSER	USER
1830;
1831	DEFB	'L'	     ;LIST ASSIGNMENTS
1832	DEFB	'T'	     ;LTTY	LIST=TELEPRINTER
1833	DEFB	'C'	     ;LCRT	LIST=CRT
1834	DEFB	'L'	     ;LINE PRINTER
1835	DEFB	'U'	     ;LUSER	USER
1836;
1837;
1838; THIS IS A SHORT PROGRAM, EXECUTED
1839; UPON EXECUTING A "GO" COMMAND. IT
1840; IS PLACED IN THE WORK AREA WHEN
1841; THE MONITOR IS INITIALIZED, AS IT
1842; REQUIRES RAM FOR PROPER OPERATION.
1843;
1844EXIT:			     ;EXIT ROUTINE (LOADS ALL REGISTERS)
1845	POP	BC
1846	LD	A,C
1847	LD	R,A
1848	LD	A,B
1849	LD	I,A
1850	POP	IY
1851	POP	IX
1852	POP	AF
1853	POP	BC
1854	POP	DE
1855	POP	HL
1856	EX	AF,AF'
1857	EXX
1858	POP	DE
1859	POP	BC
1860	POP	AF
1861	POP	HL
1862	LD	SP,HL
1863	NOP		     ;RESERVED FOR ENABLE INTERUPTS
1864	LD	HL,0
1865	JP	0
1866;
1867	DEFW	0	     ;STORAGE AREA FOR TRAP DATA
1868	DEFB	0
1869	DEFW	0
1870	DEFB	0
1871;
1872; DISPLACEMENTS OF REGISTER
1873; STORAGE FROM NORMAL STACK
1874; LOCATION.
1875;
1876ENDX:
1877;
1878ALOC	EQU	15H
1879BLOC	EQU	13H
1880CLOC	EQU	12H
1881DLOC	EQU	11H
1882ELOC	EQU	10H
1883FLOC	EQU	14H
1884HLOC	EQU	31H
1885LLOC	EQU	30H
1886PLOC	EQU	34H
1887SLOC	EQU	17H
1888TLOC	EQU	35H
1889TLOCX	EQU	25H
1890LLOCX	EQU	20H
1891;
1892APLOC	EQU	09H
1893BPLOC	EQU	0BH
1894CPLOC	EQU	0AH
1895DPLOC	EQU	0DH
1896EPLOC	EQU	0CH
1897FPLOC	EQU	08H
1898HPLOC	EQU	0FH
1899LPLOC	EQU	0EH
1900XLOC	EQU	07
1901YLOC	EQU	05
1902RLOC	EQU	02
1903ILOC	EQU	03
1904;
1905;
1906; THIS IS THE TABLE USED TO DETERMINE
1907; A VALID REGISTER IDENTIFIER, AND IT'S
1908; DISPLACEMENT FROM THE STACK POINTER.
1909;
1910; POSITION ONE= REGISTER NAME, WITH BIT 7 INDICATING
1911; END OF TABLE.
1912;
1913; POSITION TWO=	BIAS FROM CURRENT STACK LEVEL OR'ED
1914; WITH A TWO-BIT FLAG.	00XXXXXX=BYTE
1915;			10XXXXXX=WORD
1916;			11XXXXXX=SPECIAL FOR "M" REG.
1917;
1918ACTBL:		;NORMAL SET OF REGISTERS (8080)
1919;		;PLUS THE INTERUPT REGISTER ("I")
1920;
1921	DEFB	'A',ALOC | 0
1922	DEFB	'B',BLOC | 0
1923	DEFB	'C',CLOC | 0
1924	DEFB	'D',DLOC | 0
1925	DEFB	'E',ELOC | 0
1926	DEFB	'F',FLOC | 0
1927	DEFB	'H',HLOC | 0
1928	DEFB	'L',LLOC | 0
1929	DEFB	'M',HLOC | 0C0H
1930	DEFB	'P',PLOC | 080H
1931	DEFB	'S',SLOC | 080H
1932	DEFB	'I',ILOC | 0
1933	DEFB	80H
1934;
1935PRMTB:		;ADDITIONAL SET OF REGISTERS (Z-80)
1936;
1937	DEFB	'A',APLOC | 0
1938	DEFB	'B',BPLOC | 0
1939	DEFB	'C',CPLOC | 0
1940	DEFB	'D',DPLOC | 0
1941	DEFB	'E',EPLOC | 0
1942	DEFB	'F',FPLOC | 0
1943	DEFB	'H',HPLOC | 0
1944	DEFB	'L',LPLOC | 0
1945	DEFB	'M',HPLOC | 0C0H
1946	DEFB	'X',XLOC | 080H
1947	DEFB	'Y',YLOC | 080H
1948	DEFB	'R',RLOC | 0
1949	DEFB	80H
1950;
1951Z:
1952		;END OF PROGRAM
1953;
1954;
1955	END
1956