1        TITLE '<APPLE MONITOR, *ECT ROM* V1.0  JAN 07, 1979>'
2;
3; "APPLE MONITOR" COPYRIGHT 1975,1976,1977
4; BY ROGER AMIDON
5;
6; THIS MONITOR IS 8080 CODE ONLY
7;
8; MAY 2018 BY UDO MUNK:
9;       TYPED IN FROM MANUAL USING INTEL SYNTAX TO ASSEMBLE
10;       WITH INTEL MACRO 80 OR DRI 8080 ASSEMBLER
11;
12BASE    EQU  0F000H             ;ROM STARTING ADDRESS
13USER    EQU  BASE+800H
14;
15;       THIS VERSION WRITTEN FOR ELECTRONIC CONTROL TECHNOLOGY
16;                 ALL RIGHTS RESERVED
17;
18IO      EQU  0                  ;I/O PORT BASE
19;
20RST7    EQU  38H                ;RST 7 (LOCATION FOR TRAP)
21;
22;       <I/O DEVICES>
23;
24;-C.R.T. SYSTEM
25;
26CRTI    EQU  IO+1H              ;DATA PORT (IN)
27CRTS    EQU  IO+0H              ;STATUS PORT (IN)
28CRTO    EQU  IO+1H              ;DATA PORT (OUT)
29CRTDA   EQU  1                  ;DATA AVAILABLE MASK
30CRTBE   EQU  80H                ;XMTR BUFFER EMPTY MASK
31;
32;-PRINTER
33;
34TTI     EQU  IO+3H              ;DATA IN PORT
35TTO     EQU  IO+3H              ;DATA OUT PORT
36TTS     EQU  IO+2H              ;STATUS PORT (IN)
37TTYDA   EQU  1                  ;DATA AVAILABLE MASK BIT
38TTYBE   EQU  80H                ;XMTR BUFFER EMPTY MASK
39;
40;-DATA TRANSFER SYSTEM
41;
42RCSD    EQU  IO+5H              ;DATA IN PORT
43RCSS    EQU  IO+4H              ;STATUS PORT (IN)
44RCSDA   EQU  1                  ;DATA AVAILABLE MASK
45PCASO   EQU  IO+5H              ;DATA PORT (OUT)
46PCSBE   EQU  80H                ;XMTR BUFFER EMPTY MASK
47;
48; PARALLEL PORT
49;
50PPDATA  EQU  IO+7               ;PARALLEL DATA PORT
51PPSTAT  EQU  IO+6               ;PARALLEL STATUS PORT
52PPDA    EQU  1                  ;DATA AVAILABLE
53PPBE    EQU  80H                ;CLEAR TO TRANSMIT DATA
54;
55;       <CONSTANTS>
56;
57FALSE   EQU  0                  ;ISN'T SO
58TRUE    EQU  NOT FALSE          ;IT IS SO
59CR      EQU  0DH                ;ASCII CARRIAGE RETURN
60LF      EQU  0AH                ;ASCII LINE FEED
61BELL    EQU  7                  ;DING
62RUB     EQU  0FFH               ;RUB OUT
63FIL     EQU  0                  ;FILL CHARACTER AFTER CRLF
64MAX     EQU  7                  ;NUMBER OF QUES IN EOF
65;
66;       <I/O CONFIGURATION MASKS>
67;
68CMSK    EQU  11111100B          ;CONSOLE DEVICE
69RMSK    EQU  11110011B          ;STORAGE DEVICE (IN)
70PMSK    EQU  11001111B          ;STORAGE DEVICE (OUT)
71LMSK    EQU  00111111B          ;LIST DEVICE
72;
73;-CONSOLE CONFIGURATION
74CCRT    EQU  0                  ;C.R.T.
75CTTY    EQU  1                  ;PRINTER
76BATCH   EQU  2                  ;READER FOR INPUT, LIST FOR OUTPUT
77CUSE    EQU  3                  ;USER DEFINED
78;
79;-STORAGE INPUT CONFIGURATION
80RPTR    EQU  0                  ;DATA TRANSFER DEVICE
81RTTY    EQU  4                  ;PRINTER DEVICE
82RCAS    EQU  8                  ;PARALLEL PORT
83RUSER   EQU  0CH                ;USER DEFINED
84;
85;-STORAGE OUTPUT CONFIGURATION
86PPTP    EQU  0                  ;DATA TRANSFER DEVICE
87PTTY    EQU  10H                ;PRINTER PUNCH
88PCAS    EQU  20H                ;PARALLEL PORT
89PUSER   EQU  30H                ;USER DEFINED
90;
91;-LIST DEVICE CONFIGURATION
92LTTY    EQU  0                  ;CONSOLE DEVICE
93LCRT    EQU  40H                ;PRINTER
94LINE    EQU  80H                ;DATA TRANSFER DEVICE
95LUSER   EQU  0C0H               ;USER DEFINED
96;
97;
98;       VECTORS FOR USER DEFINED ROUTINES
99;
100CILOC   EQU  USER               ;CONSOLE INPUT
101COLOC   EQU  CILOC+3            ;CONSOLE OUTPUT
102CSLOC   EQU  COLOC+3            ;CONSOLE INPUT STATUS ROUTINE
103RULOC   EQU  CSLOC+3            ;USER DEFINED STORAGE (INPUT)
104PULOC   EQU  RULOC+3            ;USER DEFINED STORAGE (OUTPUT)
105LULOC   EQU  PULOC+3            ;USER DEFINED PRINTER (LIST)
106J       EQU  LULOC+3
107;
108;       PROGRAM CODE BEGINS HERE
109;
110        ORG  BASE
111;
112APPLE:  JMP  BEGIN              ;GO AROUND VECTORS
113;
114;       <VECTORS FOR CALLING PROGRAMS>
115;
116; THESE VECTORS MAY BE USED BY USER WRITTEN
117; PROGRAMS TO SIMPLIFY THE HANDLING OF I/O
118; FROM SYSTEM TO SYSTEM.  WHATEVER THE CURRENT
119; ASSIGNED DEVICE, THESE VECTORS WILL PERFORM
120; THE REQUIRED I/O OPERATIION, AND RETURN TO
121; THE CALLING PROGRAM. (RET)
122;
123; THE REGISTER CONVENTION USED FOLLOWS-
124;
125; ANY INPUT OR OUTPUT DEVICE-
126;       CHARACTER TO BE OUTPUT IN 'C' REGISTER.
127;       CHARACTER WILL BE IN 'A' REGISTER UPON
128;       RETURNING FROM AN INPUT OR OUTPUT.
129; 'CSTS'-
130;       RETURNS TRUE (0FFH IN 'A' REG.) IF THERE IS
131;       SOMETHING WAITING, AND ZERO (00) IF NOT.
132; 'IOCHK'-
133;       RETURNS WITH THE CURRENT I/O CONFIGURATION
134;       BYTE IN 'A' REGISTER.
135; 'IOSET'-
136;       ALLOWS A PROGRAM TO DYNAMICALLY ALTER THE
137;       CURRENT I/O CONFIGURATION, AND REQUIRES
138;       THE NEW BYTE IN 'C' REGISTER.
139; 'MEMCK'-
140;       RETURNS WITH THE HIGHEST ALLOWED USER
141;       MEMORY LOCATION. 'B'=HIGH BYTE, 'A'=LOW.
142; 'TRAP'-
143;       THIS IS THE 'BREAKPOINT' ENTRY POINT,
144;       BUT MAY BE 'CALLED'. IT WILL SAVE
145;       THE MACHINE STATE. RETURN CAN BE MADE WITH
146;       A SIMPLE 'G[CR]' ON THE CONSOLE.
147;
148        JMP  CI                 ;CONSOLE INPUT
149        JMP  RI                 ;READER INPUT
150        JMP  CO                 ;CONSOLE OUTPUT
151        JMP  PO                 ;PUNCH OUTPUT
152        JMP  LO                 ;LIST OUTPUT
153        JMP  CSTS               ;CONSOLE STATUS
154        JMP  IOCHK              ;I/O ASSIGNMENT CHECK
155        JMP  IOSET              ;I/O SET
156        JMP  MEMCK              ;MEMORY LIMIT CHECK
157;
158TRAP:   PUSH H                  ;ASSUME A VALID STACK
159        PUSH D
160        PUSH B
161        PUSH PSW                ;SAVE MACHINE STATE
162        LXI  D,65535-(ENDX-EXIT)
163TR0:    LXI  H,10               ;GO UP 10 BYTES IN STACK
164        DAD  SP
165        MVI  B,4
166        XCHG
167TR1:    DCX  H
168        MOV  M,D
169        DCX  H
170        MOV  M,E
171        POP  D
172        DCR  B
173        JNZ  TR1
174        POP  B                  ;OLD PC
175        DCX  B                  ;-1
176        SPHL                    ;SET MONITOR'S STACK
177        LXI  H,TLOC
178        DAD  SP
179        CALL TR5                ;TEST IF A TRAP SET
180        INX  H
181        INX  H
182        CNZ  TR5                ;TEST FOR 2ND TRAP
183        JZ   TR2                ; NO
184        INX  B
185TR2:    LXI  H,LLOC
186        DAD  SP
187        MOV  M,E
188        INX  H
189        MOV  M,D
190        INX  H
191        INX  H
192        MOV  M,C
193        INX  H
194        MOV  M,B
195        PUSH B
196        MVI  C,'@'
197        CALL CO
198        POP  H
199        CALL LADR
200        LXI  H,TLOC
201        DAD  SP
202        LXI  D,2
203TR3:    MOV  C,M
204        MOV  M,D
205        INX  H
206        MOV  B,M
207        MOV  M,D
208        INX  H
209        MOV  A,C
210        ORA  B
211        JZ   TR4
212        MOV  A,M
213        STAX B
214TR4:    INX  H
215        DCR  E
216        JNZ  TR3
217        JMP  START
218;
219TR5:    MOV  A,M
220        SUB  C
221        INX  H
222        RNZ
223        MOV  A,M
224        SUB  B
225        RET
226;
227MEMSIZ: LXI  H,-1               ;START AT THE BOTTOM
228ME0:    INR  H                  ;FIRST FIND R/W MEMORY
229        MOV  A,M
230        CMA
231        MOV  M,A
232        CMP  M
233        CMA
234        MOV  M,A
235        JNZ  ME0
236ME1:    INR  H                  ;NOW FIND NON-R/W
237        MOV  A,M
238        CMA
239        MOV  M,A
240        CMP  M
241        CMA
242        MOV  M,A
243        JZ   ME1
244        DCR  H
245        RET
246;
247MEMCK:  PUSH H
248        CALL MEMSIZ
249        MOV  B,H                ;USER'S HIGH BYTE
250        POP  H
251        MVI  A,0C0H             ;USER'S LOW BYTE
252        RET
253;
254TOM:    LXI  H,MSG
255TOM1:   MOV  C,M
256        INX  H
257        CALL CO
258        DCR  B
259        JNZ  TOM1
260        CALL CSTS
261        ORA  A
262        RZ
263;
264CCHK:   CALL KI
265        CPI  3
266        RNZ
267;
268ERROR:  LXI  SP,65535-((ENDX-EXIT)+8)
269        MVI  C,'*'
270        CALL CO
271        JMP  START
272;
273;
274;
275;
276;       ANNOUNCEMENT OF MONITOR NAME & VERSION
277;
278MSG:    DB   CR,LF,FIL,FIL,FIL
279        DB   'APPLE V'
280        DB   '1.0 ECT'
281MSGL    EQU  $-MSG
282;
283;       LET US BEGIN
284;
285BEGIN:  LXI  H,65535-(ENDX-EXIT)
286        SPHL                    ;SET UP A STACK
287        MVI  B,ENDX-EXIT
288        LXI  D,EXIT
289BG1:    LDAX D
290        MOV  M,A
291        INX  H
292        INX  D
293        DCR  B
294        JNZ  BG1
295        CALL MEMSIZ             ;GET USER'S STACK
296        PUSH H
297        MOV  H,B                ;ZERO OUT HL
298        MOV  L,B
299        PUSH H
300        PUSH H
301        PUSH H
302;       MVI  A,CONFIG ???
303        MVI  A,0
304        STA  -1
305        MVI  B,MSGL
306        CALL TOM                ;PRINT SIGN-ON
307START:  LXI  D,START
308        PUSH D
309        CALL CRLF
310        MVI  C,'>'
311        CALL CO
312        LXI  H,TBL
313STAR0:  CALL TI
314        JZ   STAR0
315        CPI  ' '                ;CONTROL?
316        JC   STAR0              ;IGNORE
317        SUI  'A'
318        RC                      ;<A
319        CPI  'Z'-'A'+1
320        RNC                     ;>Z
321        ADD  A                  ;A*2
322        ADD  L                  ;+TBL
323        MOV  L,A
324        MOV  A,M
325        INX  H
326        MOV  H,M
327        MOV  L,A
328        ANA  H
329        INR  A
330        JZ   ERROR              ;DON'T GO TO 0FFFFH
331        PCHL
332;
333;
334TBL:    DW   ASSIGN             ;A - ASSIGN I/O
335        DW   BRANCH             ;B - BRANCH TO USER ROUTINE A-Z
336        DW   OFF                ;C UNDEFINED
337        DW   DISP               ;D - DISPLAY MEMORY ON CONSOLE IN HEX
338        DW   EOF                ;E - END OF FILE TAG FOR HEX DUMPS
339        DW   FILL               ;F - FILL MEMORY WITH CONSTANT
340        DW   GOTO               ;G - GOTO <ADDRESS>, W/BKPNTS (2)
341        DW   HEXN               ;H - HEX MATH <SUM> <DIFFERENCE>
342        DW   J                  ;I *** USER DEFINED
343        DW   TEST               ;J - NON-DESTRUCTIVE MEMORY TEST
344        DW   J+3                ;K *** USER DEFINED
345        DW   LOAD               ;L - LOAD A BINARY FORMAT FILE
346        DW   MOVE               ;M - MOVE MASS MEMORY
347        DW   NULL               ;N - PUNCH LEADER/TRAILER
348        DW   J+6                ;O *** USER DEFINED
349        DW   PUTA               ;P - 'PUT' ASCII INTO MEMORY
350        DW   QUERY              ;Q - QI(N)=READ I/O; QO(N,V)=SEND I/O
351        DW   READ               ;R - READ A HEX FILE (W/CHECKSUM)
352        DW   SUBS               ;S - EXAMINE/SUBSTITUTE MEMORY
353        DW   TYPE               ;T - DISPLAY MEMORY IN ASCII
354        DW   UNLD               ;U - DUMP MEMORY IN BINARY FORMAT
355        DW   VERIFY             ;V - COMPARE MEMORY TO MEMORY
356        DW   WRITE              ;W - DUMP MEMORY IN HEX FILE FORMAT
357        DW   XAM                ;X - EXAMINE/MODIFY CPU REGISTERS
358        DW   WHERE              ;Y - FIND 'N' BYTES IN MEMORY
359        DW   SIZE               ;Z - ADDR OF LAST R/W MEMORY LOCATION
360;
361OFF     EQU  -1
362;
363UTAB    EQU  USER+80H
364;
365;
366ASSIGN: CALL TI                 ;GET A DEVICE
367        LXI  H,LTBL-1           ;POINT TO TABLE
368        LXI  B,4                ;TO SKIP THRU TABLE
369        CALL AS3                ;GET DEVICE COUNT
370        PUSH D
371AS1:    CALL TI
372        SUI  '='
373        JNZ  AS1
374        MOV  C,A                ;C=0
375        CALL TI                 ;GET ASSIGNMENT
376        CALL AS3
377        POP  PSW                ;A=DEVICE
378        MOV  L,D                ;L=ASSIGNMENT
379        MVI  H,3                ;SETUP A MASK
380AS2:    DCR  A                  ;ZERO=DONE
381        JM   AS5
382        DAD  H
383        DAD  H                  ;DOUBLE SHIFT LEFT
384        JMP  AS2
385AS3:    LXI  D,4                ;GO THRU THIS 4 TIMES
386AS4:    INX  H                  ;BUMP POINTER 1
387        CMP  M                  ;MATCH?
388        RZ                      ;YES
389        DAD  B                  ;BUMP HL
390        INR  D
391        DCR  E                  ;COUNT DOWN
392        JNZ  AS4
393        JMP  ERROR              ;CAN'T FIND IT
394;
395AS5:    XRA  A                  ;COMPLIMENT H
396        MOV  H,A
397        CALL IOCHK              ;GET CURRENT CONFIGURATION
398        ANA  H                  ;KILL ASSIGNMENT BITS
399        ORA  L                  ;MODIFY TO NEW DEVICE
400        MOV  C,A                ;PUT NEW IOBYT IN C
401;
402SZA     EQU  $-ASSIGN
403;
404IOSET:  MOV  A,C
405        STA  -1
406        RET
407;
408IOCHK:  LDA  -1
409        RET
410;
411BRANCH: CALL TI                 ;GET A '.'
412        CPI  '.'
413        JNZ  ERROR
414        LXI  H,UTAB             ;POINT TO USER'S TBL
415        JMP  STAR0              ;GOOD LUCK
416;
417SZB     EQU  $-BRANCH
418;
419SZC     EQU  $-$
420;
421DISP:   MVI  C,16               ;SET A DEFAULT
422        CALL EXPC
423        PUSH PSW
424DI0:    CALL LFADR
425        POP  PSW
426        PUSH PSW                ;GET SIZE
427        MOV  B,A                ;IN B
428DI1:    CALL BLK
429        MOV  A,M
430        CALL LBYTE
431        CALL HILO
432        JC   PRET
433        DCR  B
434        JNZ  DI1
435        JMP  DI0
436;
437SZD     EQU  $-DISP
438;
439EOF:    CALL EXPR
440        CALL PEOL
441        MVI  C,':'
442        CALL PO
443        XRA  A
444        CALL PBYTE
445        POP  H
446        CALL PADR
447        LXI  H,0
448        CALL PADR
449        JMP  NULL
450;
451SZE     EQU  $-EOF
452;
453FILL:   CALL EXPC
454FI1:    MOV  M,C
455        CALL HILO
456        JNC  FI1
457        POP  D
458        JMP  START
459;
460SZF     EQU  $-FILL
461;
462GOTO:   CALL PCHK
463        JZ   GO0                ;DELIMITER ENTERED
464        CALL EXF                ; ELSE GET A 'GO' ADDR
465        POP  D
466        LXI  H,PLOC
467        DAD  SP
468        MOV  M,D                ;PLACE IN EXIT TEMPLATE
469        DCX  H
470        MOV  M,E
471GO0:    CPI  CR                 ;TEST DELIMITER
472        JZ   GO4                ;NO BREAKPOINTS, JUST GO
473        MVI  D,2                ;2 POSSIBLE BREAKPOINTS
474        LXI  H,TLOCX
475        DAD  SP
476GO1:    PUSH H
477        CALL EXPR               ;GET AN ADDRESS
478        POP  B                  ;IN BC
479        POP  H
480        PUSH PSW                ;SAVE DELIMITER
481        MOV  A,B                ;CAN'T ALLOW ANY
482        ORA  C                  ; BREAKPOINTS AT ZERO
483        JZ   GO2
484        MOV  M,C
485        INX  H
486        MOV  M,B                ;ELSE SAVE BKPT ADDRESS
487        INX  H
488        LDAX B                  ;AND OPCODE THERE
489        MOV  M,A
490        INX  H
491        MVI  A,0FFH             ;RST 7
492        STAX B                  ;REPLACE OPCODE
493GO2:    POP  PSW                ;LOOK AT DELIMITER
494        JC   GO3
495        DCR  D
496        JNZ  GO1
497GO3:    MVI  A,0C3H             ;SET A 'JMP' AT RST 7
498        STA  RST7
499        LXI  H,TRAP
500        SHLD RST7+1
501GO4:    CALL CRLF
502        POP  D                  ;THROW AWAY RETURN
503        LXI  H,8
504        DAD  SP
505        PCHL
506;
507SZG     EQU  $-GOTO
508;
509TEST:   CALL EXPC
510TE1:    MOV  A,M
511        MOV  B,A                ;SAVE CHAR IN 'B'
512        CMA
513        MOV  M,A
514        XRA  M
515        MOV  M,B                ;REPLACE BYTE
516        JZ   TE2
517        PUSH D                  ;SAVE END POINTER
518        MOV  E,A                ;SAVE ERROR MASK
519        CALL HLSP               ;DISPLAY BAD ADDRESS
520        CALL BITS+1             ;DISPLAY BAD BIT(S)
521        POP  D                  ;RESTORE DE
522TE2:    CALL HILOX
523        JMP  TE1
524;
525SZJ     EQU  $-TEST
526;
527LOAD:   CALL EXPR
528        CALL CRLF
529        POP  H
530        MVI  D,RUB
531LO0:    LXI  B,407H             ;B=4 MATCHES, C=BELL
532LO1:    CALL RIFF
533        JNZ  LO0
534        DCR  B
535        JNZ  LO1
536LO2:    CALL RIFF
537        JZ   LO2
538        MOV  M,A
539        CALL CO                 ;TELL CONSOLE
540LO3:    INX  H
541        CALL RIFF
542        JZ   LO5
543LO4:    MOV  M,A
544        JMP  LO3
545LO5:    MVI  E,1                ;INITIALIZE
546LO6:    CALL RIFF
547        JNZ  LO7
548        INR  E
549        MVI  A,MAX
550        CMP  E
551        JNZ  LO6
552        JMP  LFADR
553LO7:    MOV  M,D
554        INX  H
555        DCR  E
556        JNZ  LO7
557        JMP  LO4
558;
559SZL     EQU  $-LOAD
560;
561MOVE:   CALL EXPC
562MO:     MOV  A,M
563        STAX B
564        INX  B
565        CALL HILOX
566        JMP  MO
567;
568SZM     EQU  $-MOVE
569;
570PUTA:   CALL EXPR
571        CALL CRLF
572        POP  H
573PU0:    CALL KI
574        CPI  4                  ;EOT?
575        JZ   LFADR              ;PRINT ADDRESS & QUIT
576        CPI  7FH                ;RUB-OUT?
577        JZ   PU2                ; YES
578        MOV  M,A                ;PUT CHARACTER INTO MEMORY
579        MOV  C,A
580        INX  H
581PU1:    CALL CO                 ;ECHO CHARACTER
582        JMP  PU0                ;& CONTINUE
583PU2:    DCX  H                  ;BACK-UP POINTER
584        MOV  C,M                ;ECHO CANCELED CHARACTER
585        JMP  PU1
586;
587SZP     EQU  $-PUTA
588;
589WHERE:  LXI  H,0                ;GET STRING POINTER (SP)
590        MOV  C,L                ;ZERO C REG
591        DAD  SP
592        DCX  H                  ;SP-1
593        XCHG                    ;SAVE IN DE
594WH1:    CALL EXPR
595        POP  H                  ;CONSERVE STACK USAGE
596        MOV  H,L                ;L=SEARCH BYTE
597        PUSH H                  ;H=L
598        INX  SP                 ;ADJUST STACK
599        INR  C                  ;COUNT SEARCH BYTES
600        JNC  WH1
601        XCHG
602        MOV  D,C
603        PUSH H                  ;HL=SEARCH STRING POINTER
604        LXI  B,0
605        PUSH B                  ;BC=START SEARCH (0)
606WH2:    CALL CRLF
607WH3:    POP  B
608        POP  H
609        MOV  E,D
610        MOV  A,B
611        ANA  C
612        INR  A
613        JNZ  WH5
614WH4:    INX  H
615        SPHL                    ;RESET STACK
616        RET
617WH5:    LDAX B
618        INX  B
619        CMP  M
620        PUSH H
621        PUSH B
622WH6:    JNZ  WH3
623        DCR  E
624        JZ   WH7
625        LDAX B
626        INX  B
627        DCX  H
628        CMP  M
629        JMP  WH6
630WH7:    POP  H
631        PUSH H
632        DCX  H
633        CALL LADR
634        JMP  WH2
635;
636SZY     EQU  $-WHERE
637;
638READ:   CALL EXPR               ;GET 16 BIT VALUE
639        POP  D                  ;DE=BIAS
640        LXI  H,0                ;SET-UP DEFAULT BASE[1]
641        PUSH H                  ;AND DEFAULT BASE[2]
642        JC   RD0                ;CR
643        CALL EXPR               ;GET ACTUAL BASE[1]
644        POP  H                  ;HL=BASE[1]
645        JC   RD0                ;CR
646        XTHL                    ;GET DEFAULT BASE[2]
647        CALL EXPR               ;GET ACTUAL BASE[2]
648        POP  H
649        XTHL                    ;(SP)=BASE[2]
650RD0:    PUSH H                  ;HL=BASE[1]
651        PUSH D                  ;DE=BIAS
652        CALL CRLF               ;BEGIN READING FILE
653RD1:    CALL RIX                ;GET READER CHARACTER
654        SUI  ':'                ;GET FILE TYPE CUE
655        MOV  B,A                ;SAVE CUE CLUE
656        ANI  0FEH               ;KILL BIT 0
657        JNZ  RD1                ;NOT ':' OR ';'
658        MOV  D,A                ;ZERO CHECKSUM STORAGE
659        CALL BYTE               ;GET FILE LRNGTH
660        MOV  E,A                ;SAVE IN E
661        CALL BYTE               ;GET LOAD MSB
662        PUSH PSW                ;SAVE IN STACK
663        CALL BYTE               ;GET LOAD LSB
664        POP  H                  ;H=MSB
665        MOV  L,A                ;HL=LOAD ADDR
666        CALL BYTE               ;GET FILE TYPE
667        ORA  A                  ;TEST FILE TYPE
668        MOV  A,B                ;GET CUE
669        POP  B                  ;BC=BIAS
670        JZ   RD2                ;ABSOLUTE LOAD
671        XCHG                    ;RELOCATE LOAD ADDR.
672        XTHL
673        XCHG
674        DAD  D                  ;DO IT
675        XCHG
676        XTHL
677        XCHG                    ;HL=LOAD+BASE[1]
678RD2:    INR  E                  ;TEST LENGTH
679        DCR  E                  ;ZERO?
680        JZ   DONE
681        DAD  B                  ;ADD BIAS TO LOAD
682        PUSH B                  ;SAVE BIAS
683        MOV  B,A                ;SET-UP B
684        DCR  A                  ;TEST CUE CLUE
685        JZ   RD6                ;Z=REL. FILE, NZ=ABS.
686RD3:    CALL BYTE               ;GET NEXT DATA BYTE
687        MOV  M,A                ;WRITE TO MEMORY
688        INX  H                  ;BUMP UP LOAD POINT
689        DCR  E                  ;BUMP DOWN BYTE COUNT
690        JNZ  RD3                ;CONTINUE
691RD4:    CALL BYTE               ;TEST CHECKSUN
692        JZ   RD1                ;OK; CONTINUE W/NEXT
693RD5:    CALL LADR               ; ELSE PRINT LOAD ADDR
694        JMP  ERROR              ; & ABORT
695RD6:    CALL RD10               ;GET NEXT DATA BYTE
696        MOV  M,A                ;STORE IT
697        JNC  RD9                ;NORMAL BYTE
698        PUSH H                  ;CARRY=RELOCATE NEXT WORD
699        LXI  H,5                ;POINT TO BASE[1]
700        DAD  SP                 ;IN STACK
701RD7:    CALL RD10               ;GET HIGH BYTE
702        JNC  RD8                ;USE BASE[N]
703        DCR  E                  ;COUNT EXTRA BYTE
704        XTHL                    ;GET LOAD ADDR
705        DCR  M                  ;TEST FOR BASE[1]
706        MOV  M,A                ;NEW LOW BYTE
707        XTHL                    ;SAVE LOAD AGAIN
708        JZ   RD7                ;BASE[1]
709        INX  H
710        INX  H                  ;POINT TO BASE[2]
711        JMP  RD7                ;AND TRY AGAIN
712;
713RD8:    ADD  M                  ;ADD IN MSB
714        XTHL
715        INX  H                  ;STICK AT LOAD+1
716        MOV  M,A
717        DCX  H                  ;GET LOAD BYTE
718        MOV  A,M                ;IN A
719        XTHL
720        DCX  H
721        ADD  M                  ;RELOCATE LSB
722        POP  H                  ;GET LOAD ADDR
723        MOV  M,A                ;STORE IT
724        INX  H                  ;GET MSB
725        MOV  A,M                ;IN A
726        ACI  0                  ;ADJUST FOR CARRY
727        MOV  M,A                ;STORE IT
728        DCR  E                  ;COUNT IT
729RD9:    INX  H                  ;BUMP THE COUNT
730        DCR  E                  ;MORE?
731        JNZ  RD6                ; & CONTINUE
732        JMP  RD4                ;TEST CHECKSUM
733;
734RD10:   DCR  B                  ;COUNT BITS/BYTES
735        JNZ  RD11               ;NEXT IS DATA BYTE
736        CALL BYTE               ;GET RELOC. MAP
737        DCR  E                  ;BUMP DOWN BYTE COUNT
738        MOV  C,A                ;MAP IN C
739        MVI  B,8                ;RESET FOR NEXT 8
740RD11:   CALL BYTE               ;NEXT DATA BYTE
741        PUSH D                  ;SAVE DE
742        MOV  D,A                ;SAVE DATA BYTE
743        MOV  A,C                ;TEST FOR RELOC.
744        RAL                     ;IN CARRY FLAG
745        MOV  C,A                ;UPDATE C
746        MOV  A,D                ;RESTORE DATA BYTE
747        POP  D                  ;RESTORE DE
748        RET                     ;CONTINUE
749;
750BYTE:   PUSH B                  ;SAVE BC
751        CALL RIBBLE             ;GET A CONVERTED CHAR.
752        RLC
753        RLC
754        RLC
755        RLC                     ;MOVE IT TO HIGH NIBBLE
756        MOV  C,A                ;SAVE IT
757        CALL RIBBLE             ;GET OTHER HALF
758        ORA  C                  ;MAKE WHOLE
759        MOV  C,A                ;SAVE IN C
760        ADD  D                  ;UPDATE CHECKSUM
761        MOV  D,A                ;NEW CHECKSUM
762        MOV  A,C                ;RESTORE DATA BYTE
763        POP  B                  ;RESTORE BC
764        RET                     ;CONTINUE
765;
766DONE:   POP  B                  ;BASE[1]
767        POP  B                  ;BASE[2]
768        MOV  A,H                ;TEST EOF
769        ORA  L                  ;FOR ZERO
770        RZ
771        XCHG                    ;ELSE STORE IT IN 'P'
772        LXI  H,PLOC
773        DAD  SP
774        MOV  M,D                ;IN 'EXIT' TEMPLATE
775        DCX  H
776        MOV  M,E
777        RET                     ;REALLY DONE.
778;
779SZR     EQU  $-READ
780;
781SUBS:   CALL EXPR
782        POP  H
783        RC                      ;QUIT
784SU0:    MOV  A,M
785        CALL LBYTE
786        CALL COPCK
787        RC
788        JZ   SU1
789;       CPI  '_'                ;BACK-UP?
790        CPI  5FH                ;*UM*
791        JZ   SU3
792        PUSH H
793        CALL EXF
794        POP  D
795        POP  H
796        MOV  M,E
797        RC
798SU1:    INX  H
799SU2:    MOV  A,L
800        ANI  7
801        CZ   LFADR
802        JMP  SU0
803SU3:    DCX  H                  ;BACK-UP
804        JMP  SU2
805;
806SZS     EQU  $-SUBS
807;
808TYPE:   MVI  C,64               ;SET UP A DEFAULT
809        CALL EXPC
810        PUSH PSW
811TY0:    CALL LFADR
812        POP  PSW
813        PUSH PSW
814        MOV  B,A                ;RESET LENGTH
815TY1:    MOV  A,M
816        ANI  7FH
817        CPI  ' '                ;TEST LOWER END
818        JNC  TY3
819TY2:    MVI  A,'.'              ;PRINT PERIODS INSTEAD
820TY3:    CPI  7DH                ;TEST UPPER END
821        JNC  TY2
822        MOV  C,A                ;PUT WHATEVER INTO C
823        CALL CO
824        CALL HILO
825        JC   PRET
826        DCR  B
827        JNZ  TY1
828        JMP  TY0
829;
830SZT     EQU  $-TYPE
831;
832VERIFY: CALL EXPC
833VE0:    LDAX B
834        PUSH D                  ;SAVE END POINTER
835        MOV  E,M                ;GET MEMORY DATA
836        CMP  E                  ;TEST FOR MATCH
837        JZ   VE1                ;MATCHES
838        PUSH B
839        MOV  B,A
840        CALL HLSP
841        MOV  A,E                ;GET MISMATCH
842        CALL LBYTE              ;PRINT IT
843        CALL BLK                ;SPACE OVER
844        MOV  A,B                ;GET OTHER MISMATCH
845        CALL LBYTE              ;PRINT THAT TOO
846        CALL CRLF               ;PREPARE FOR ANOTHER
847        POP  B
848VE1:    POP  D                  ;RESTORE END POINTER
849        INX  B
850        CALL HILOX
851        JMP  VE0
852;
853SZV     EQU  $-VERIFY
854;
855WRITE:  CALL EXPC
856        CALL WAIT
857WR0:    CALL PEOL
858        LXI  B,':'
859        CALL PO
860        PUSH D
861        PUSH H
862WR1:    INR  B
863        CALL HILO
864        JC   WR2
865        MVI  A,24
866        SUB  B
867        JNZ  WR1
868        POP  H
869        CALL WR3
870        POP  D
871        JMP  WR0
872WR2:    POP  H
873        POP  D
874WR3:    MOV  A,B
875        CALL PBYTE              ;PUNCH FILE SIZE
876        CALL PADR               ;AND ADDR.
877        MOV  A,B                ;SET-UP CHECKSUM
878        ADD  H
879        ADD  L
880        MOV  D,A                ;CHECKSUM IN D
881        XRA  A                  ;ZERO FILE TYPE
882        CALL PBYTE
883WR4:    MOV  A,M
884        ADD  D                  ;UPDATE CHECKSUM
885        MOV  D,A
886        MOV  A,M
887        CALL PBYTE
888        INX  H
889        DCR  B
890        JNZ  WR4
891        XRA  A
892        SUB  D
893        JMP  PBYTE
894;
895SZW     EQU  $-WRITE
896;
897XAM:    CALL PCHK
898        LXI  H,ACTBL            ;POINT TO REG. TABLE
899        MVI  B,ACTSZ            ;SET UP B
900        JC   XA6
901XA0:    CMP  M                  ;VALID REG. NAME?
902        JZ   XA1                ; YES
903        INX  H                  ;ELSE TEST NEXT ONE
904        INX  H                  ;SKIP OFFSET
905        DCR  B                  ;END OF TABLE?
906        JZ   ERROR              ; YES
907        JMP  XA0                ;ELSE KEEP LOOKING
908XA1:    CALL BLK
909XA2:    CALL XA8                ;GET & PRINT REG(S)
910XA3:    CALL COPCK              ;MODIFY?
911        JZ   XA5                ; NO, DELIMITER ENTERED
912        PUSH H                  ;SAVE TABLE POINTER
913        PUSH B                  ;SAVE FLAG TEST (B)
914        CALL EXF                ;GET NEW VALUE
915        POP  H                  ;IN HL
916        POP  B                  ;B=FLAG BYTE
917        PUSH PSW                ;A=DELIMITER
918        MOV  A,L                ;L=LOW BYTE
919        STAX D                  ;STORE IT
920        MOV  A,B                ;GET FLAG
921        RAL                     ;TEST BIT 7
922        JNC  XA4                ;SINGLE BYTE
923        INX  D                  ;ELSE
924        MOV  A,H                ; SAVE
925        STAX D                  ;  HIGH BYTE
926XA4:    POP  PSW                ;GET DELIMITER
927        POP  H                  ;RESTORE TABLE POINTER
928XA5:    RC                      ;CR=DONE
929        MOV  A,M                ;END OF TABLE?
930        ORA  A                  ;TEST BIT 7
931        RM                      ;YES, DONE
932        JMP  XA2                ;ELSE CONTINUE
933;
934XA6:    CALL CRLF               ;FULL REGISTER DISPLAY
935XA7:    CALL BLK                ;SPACE OVER
936        MOV  A,M                ;GET REGISTER NAME
937        ORA  A                  ;END OF TABLE?
938        RM                      ;YES, RETURN
939        MOV  C,A                ;ELSE PRINT IDENTIFIER
940        CALL CO                 ; ON CONSOLE
941        MVI  C,'='              ;FOR READABILITY
942        CALL CO
943        CALL XA8                ;GET & PRINT REG(S)
944        JMP  XA7
945XA8:    INX  H                  ;POINT TO DISPLACEMENT
946        MOV  A,M                ;GET IT
947        INX  H                  ;POINT TO NEXT IN TABLE
948        XCHG                    ;SAVE IN DE
949        MOV  B,A                ;SAVE FOR FLAGS
950        ANI  3FH                ;KILL FLAGS
951        MOV  L,A                ;CALCULATE DISPLACEMENT
952        MVI  H,0
953        DAD  SP                 ;UP IN STACK
954        INX  H                  ;ADJUST FOR RET IN STACK
955        INX  H
956        MOV  A,B                ;TEST FOR 'M'
957        ANI  40H                ;BIT 6
958        JZ   XA9                ;NO, NOT 'M'
959        MOV  A,M                ;ELSE GET 'M' POINTER
960        DCX  H                  ; INSTEAD
961        MOV  L,M                ;  IN HL
962        MOV  H,A                ;   (WHERE ELSE)
963XA9:    MOV  A,M                ;GET THE VALUE
964        CALL LBYTE              ;AND PRINT IT
965        XCHG                    ;SWITCH POINTERS
966        MOV  A,B                ;TEST FLAG
967        RAL                     ;SINGLE OR DOUBLE?
968        RNC                     ;SINGLE
969        DCX  D                  ;DOUBLE
970        LDAX D                  ;GET IT
971        JMP  LBYTE              ;PRINT IT & RETURN
972;
973SZX     EQU  $-XAM
974;
975QUERY:  CALL TI                 ;SEE IF IN OR OUT
976        LXI  H,QLOC             ;PRESET
977        DAD  SP                 ;TO ROUTINE IN EXIT AREA
978        PUSH H                  ;FOR BOTH ROUTINES
979        CPI  'O'                ;OUT?
980        JNZ  QI                 ; NO, MUST BE IN
981        CALL EXPC               ;GET PORT & VALUE
982        MOV  A,E                ;L=PORT E=VALUE
983        MOV  C,L
984        POP  H
985        MOV  M,C
986        DCX  H
987        MVI  M,0D3H             ;SET FOR OUTPUT
988        PCHL                    ;DO IT & RETURN
989;
990QI:     CPI  'I'
991        JNZ  ERROR
992        CALL EXPR
993        POP  B
994        LXI  H,BITS             ;SET-UP A RETURN
995        XTHL
996        MOV  M,C                ;SET PORT NUMBER
997        DCX  H
998        MVI  M,0DBH             ;SET FOR INPUT
999        PCHL                    ;DO IT
1000;
1001SZQ     EQU  $-QUERY
1002;
1003SIZE:   CALL MEMSIZ
1004;
1005LFADR:  CALL CRLF
1006;
1007HLSP:   CALL LADR
1008;
1009BLK:    MVI  C,' '
1010;
1011CO:     LDA  -1
1012        ANI  NOT CMSK
1013        JZ   CRTOUT
1014        DCR  A
1015        JNZ  COU
1016;
1017TTYOUT: IN   TTS
1018        ANI  TTYBE
1019        JNZ  TTYOUT
1020        MOV  A,C
1021        OUT  TTO
1022        RET
1023;
1024CRTOUT: IN   CRTS
1025        ANI  CRTBE
1026        JNZ  CRTOUT
1027        MOV  A,C
1028        OUT  CRTO
1029        RET
1030;
1031COU:    DCR  A                  ;BATCH
1032        JNZ  COLOC              ;NO
1033;
1034LO:     LDA  -1
1035        ANI  NOT LMSK
1036        JZ   CRTOUT             ;USE MAIN CONSOLE
1037        CPI  LCRT
1038        JZ   TTYOUT             ;USE PRINTER
1039        CPI  LINE
1040        JNZ  LULOC              ;MUST BE USER DEFINED
1041                                ;ELSE USE DATA TRANSFER
1042LNLOC:  IN   RCSS
1043        ANI  PCSBE
1044        JNZ  LNLOC
1045        MOV  A,C
1046        OUT  PCASO
1047        RET
1048;
1049CONV:   ANI  0FH
1050        ADI  90H
1051        DAA
1052        ACI  40H
1053        DAA
1054        MOV  C,A
1055        RET
1056;
1057BITS:   MOV  E,A
1058        MVI  D,8
1059        CALL BLK
1060BI:     MOV  A,E
1061        RAL
1062        MOV  E,A
1063        MVI  A,0
1064        ACI  '0'
1065        MOV  C,A
1066        CALL CO
1067        DCR  D
1068        JNZ  BI
1069;
1070CRLF:   PUSH H
1071        PUSH B                  ;SAVE BC
1072        MVI  B,5
1073        CALL TOM
1074        POP  B
1075        POP  H
1076        RET
1077;
1078CSTS:   LDA  -1
1079        ANI  NOT CMSK
1080        JZ   CS1                ;CRT
1081        DCR  A
1082        JZ   CS0                ;TTY
1083        DCR  A
1084        RZ                      ;BATCH MODE
1085        JMP  CSLOC              ;USER
1086;
1087CS0:    IN   TTS
1088        ANI  TTYDA
1089        JMP  CS2
1090;
1091CS1:    IN   CRTS
1092        ANI  CRTDA
1093CS2:    MVI  A,TRUE
1094        RZ
1095        CMA
1096        RET
1097;
1098; THIS ROUTINE WILL GET TWO PARAMETERS
1099; FROM THE KEYBOARD, AND RETURN WITH THE
1100; 'C' REEGISTER IN A, & CARRY SET IF THE
1101; TERMINATOR WAS A CARRIAGE RETURN. OTHERWISE,
1102; IT WILL GET THE THIRD PARAMETER. IF THE
1103; THIRD PARAMETER IS NON-ZERO, IT WILL RETURN
1104; WITH THE THIRD PARAMETER IN 'A'. IF IT IS
1105; ZERO, IT WILL RETURN WITH THE DEFAULT PARAM.
1106; - IN EITHER CASE, IF THREE PARAMETERS WERE
1107; ENTERED, IT WILL RETURN WITH THE CARRY CLEAR.
1108;
1109EXPC:   PUSH B                  ;SAVE DEFAULT PARAMETER
1110        CALL EXPR               ;GET 1ST.
1111        JC   ERROR              ;CR ENTERED TOO SOON
1112        CALL EXPR               ;GET 2ND. PARAMETER
1113        POP  D                  ;2ND. IN DE
1114        POP  H                  ;1ST. IN HL
1115        POP  B                  ;REMOVE DEFAULT
1116        PUSH H                  ;SAVE 1ST. PARAMETER
1117        MOV  A,C                ;USE DEFAULT
1118        JC   EX1                ;NO THIRD PARAMETER
1119        PUSH B                  ;SAVE DEFAULT AGAIN
1120        CALL EXPR               ;GET 3RD. PARAMETER
1121        POP  B                  ;BC=TRUE 3RD. PARAMETER
1122        MOV  A,C                ;TEST IT
1123        POP  H                  ;HL=DEFAULT
1124        ORA  A                  ;TEST LOW BYTE
1125        JNZ  EX1                ;OK, TAKE IT
1126        MOV  A,L                ;ELSE USE DEFAULT
1127EX1:    POP  H                  ;GET 1ST. PARAM
1128        PUSH PSW                ;SAVE ACC & FLAGS
1129        CALL CRLF
1130        POP  PSW
1131        RET
1132;
1133; THIS ROUTINE RETURNS ONLY IF THREE PARAMETERS
1134; WERE ENTERED. LESS THAN THREE RESULTS IN AN
1135; ERROR CONDITION.
1136;
1137EXP3:   CALL EXPC               ;GET THREE PARAMETERS
1138        JC   ERROR              ;I SAID 3
1139        RET
1140;
1141EXPR:   CALL TI                 ;GET KEYBOARD
1142EXF:    LXI  H,0                ;INITIALIZE HL
1143XF1:    MOV  B,A                ;SAVE KEYBOARD
1144        CALL NIBBLE             ;CONVERT ASCII TO HEX
1145        JC   XF2                ;BOT LEGAL
1146        DAD  H                  ;HL*16
1147        DAD  H
1148        DAD  H
1149        DAD  H
1150        ORA  L                  ;ADD IN NIBBLE
1151        MOV  L,A
1152        CALL TI                 ;GET NEXT KEYBORAD
1153        JMP  XF1                ;AND CONTINUE
1154XF2:    XTHL                    ;STICK PARAMETER IN STACK
1155        PUSH H                  ;REPLACE RETURN
1156        MOV  A,B                ;TEST CHARACTER
1157        CALL QCHK               ;FOR DELIMITERS
1158        JNZ  ERROR              ;ILLEGAL
1159        RET
1160;
1161HILOX:  CALL HILO
1162        RNC                     ;RETURN IF OK
1163PRET:   POP  D                  ;ELSE RETURN
1164        RET                     ; ONE LEVEL BACK
1165;
1166HILO:   INX  H
1167        MOV  A,H
1168        ORA  L
1169        STC
1170        RZ
1171        MOV  A,E
1172        SUB  L
1173        MOV  A,D
1174        SBB  H
1175        RET
1176;
1177HEXN:   CALL EXPC
1178        PUSH H
1179        DAD  D
1180        CALL HLSP
1181        POP  H
1182        MOV  A,L
1183        SUB  E
1184        MOV  L,A
1185        MOV  A,H
1186        SBB  D
1187        MOV  H,A
1188;
1189SZH     EQU  $-HEXN
1190;
1191LADR:   MOV  A,H
1192        CALL LBYTE
1193        MOV  A,L
1194;
1195LBYTE:  PUSH PSW
1196        RRC
1197        RRC
1198        RRC
1199        RRC
1200        CALL LB
1201        POP  PSW
1202LB:     CALL CONV
1203        JMP  CO
1204;
1205MARK:   LXI  B,08FFH            ;PRESET FOR RUB-OUTS
1206        JMP  LEED
1207;
1208LEAD:   LXI  B,4800H            ;PRESET FOR NULLS
1209LEED:   CALL PO
1210        DCR  B
1211        JNZ  LEED
1212        RET
1213;
1214RIBBLE: CALL RIX
1215NIBBLE: SUI  '0'
1216        RC
1217        CPI  'G'-'0'
1218        CMC
1219        RC
1220        CPI  10
1221        CMC
1222        RNC
1223        SUI  'A'-'9'-1
1224        CPI  10
1225        RET
1226;
1227PADR:   MOV  A,H
1228        CALL PBYTE
1229        MOV  A,L
1230;
1231PBYTE:  PUSH PSW
1232        RRC
1233        RRC
1234        RRC
1235        RRC
1236        CALL PBL
1237        POP  PSW
1238PBL:    CALL CONV
1239        JMP  PO
1240;
1241COPCK:  MVI  C,'-'
1242        CALL CO
1243;
1244PCHK:   CALL TI
1245;
1246QCHK:   CPI  ' '
1247        RZ
1248        CPI  ','
1249        RZ
1250        CPI  CR
1251        STC
1252        RZ
1253        CMC
1254        RET
1255;
1256PEOL:   MVI  C,CR
1257        CALL PO
1258        MVI  C,LF
1259;
1260PO:     LDA  -1
1261        ANI  NOT PMSK
1262        JZ   LNLOC              ;DATA XFER DEVICE
1263        CPI  PTTY
1264        JZ   TTYOUT             ;PRINTER DEVICE
1265        CPI  PCAS
1266        JNZ  PULOC              ;USER DEFINED
1267;
1268PTPL:   IN   PPSTAT             ;PARALLEL PORT
1269        ANI  PPBE
1270        JNZ  PTPL
1271        MOV  A,C
1272        OUT  PPDATA
1273        RET
1274;
1275UNLD:   CALL EXPC
1276        CALL WAIT
1277        CALL LEAD
1278        CALL MARK
1279UL1:    MOV  C,M
1280        CALL PO
1281        CALL HILO
1282        JNC  UL1
1283        CALL MARK
1284;
1285SZU     EQU  $-UNLD
1286;
1287NULL:   CALL LEAD
1288;
1289SZN     EQU  $-NULL
1290;
1291WAIT:   LDA  -1
1292        ANI  NOT CMSK
1293        RZ
1294;
1295CI:     LDA  -1
1296        ANI  NOT CMSK
1297        JZ   CRTIN
1298        DCR  A
1299        JNZ  CIU
1300;
1301TTYIN:  IN   TTS
1302        ANI  TTYDA
1303        JNZ  TTYIN
1304        IN   TTI
1305        RET
1306;
1307CRTIN:  IN   CRTS
1308        ANI  CRTDA
1309        JNZ  CRTIN
1310        IN   CRTI
1311        RET
1312;
1313CIU:    DCR  A                  ;BATCH?
1314        JNZ  CILOC              ; NO, MUST BE USER
1315;
1316RI:     LDA  -1
1317        ANI  NOT RMSK
1318        OUT  TTS                ;PULSE A PORT TO SHOW REQUEST
1319        JNZ  RI3                ;NEXT
1320;DATA XFER
1321RI4:    CALL RI2                ;ABORT?
1322        IN   RCSS
1323        ANI  RCSDA
1324        JNZ  RI4
1325        IN   RCSD
1326        RET
1327;
1328RI3:    CPI  RTTY               ;IS IT PRINTER
1329        JNZ  RI5                ;NEXT
1330;PRINTER
1331RI1:    CALL RI2                ;SEE IF ABORT
1332        IN   TTS
1333        ANI  TTYDA
1334        JNZ  RI1
1335        IN   TTI
1336        RET
1337;
1338RI5:    CPI  RCAS
1339        JNZ  RULOC              ;USER DEFINED
1340;PARALLEL PORT
1341RI6:    CALL RI2
1342        IN   PPSTAT
1343        ANI  PPDA
1344        JNZ  RI6
1345        IN   PPDATA
1346        RET
1347;
1348RI2:    LDA  -1                 ;MAKE SURE CONSOLE=0
1349        ANI  NOT CMSK
1350        RNZ
1351        CALL CSTS               ;ANYTHING WAITING THERE?
1352        ORA  A
1353        RZ                      ;NO, CONTINUE
1354        CALL KI                 ;ELSE GET IT
1355        CPI  3                  ;CONTROL-C?
1356        RNZ
1357        POP  PSW                ;ELSE RETURN
1358        XRA  A                  ;WITH CARRY SET
1359        STC
1360        RET
1361;
1362RIX:    CALL RIFF
1363        ANI  7FH
1364        RET
1365;
1366RIFF:   CALL RI
1367        JC   ERROR
1368        CMP  D
1369        RET
1370;
1371KI:     CALL CI                 ;GET CONSOLE CHARACTER
1372        ANI  7FH                ;KILL PARITY BIT
1373        RET
1374;
1375TI:     CALL KI
1376        RZ
1377        CPI  7FH
1378        RZ                      ;TEST FOR RUB-OUT
1379        CPI  CR                 ;IGNORE CR'S
1380        RZ
1381        PUSH B
1382        MOV  C,A
1383        CALL CO
1384        MOV  A,C
1385        POP  B
1386        CPI  'A'-1              ;CONVERT TO UPPER CASE
1387        RC
1388;       CPI  'z'+1
1389        CPI  7BH                ;*UM*
1390        RNC
1391        ANI  05FH
1392        RET
1393;
1394;
1395; <SYSTEM I/O LOOK-UP TABLE>
1396;
1397; THE FIRST CHARACTER IS THE DEVICE NAME
1398; (ONE LETTER) AND THE NEXT FOUR ARE THE
1399; NAMES OF THE FOUR POSSIBLE DRIVERS TO BE
1400; ASSIGNED.
1401;
1402LTBL:
1403;
1404        DB   'C'                ;CONSOLE ASSIGNMENTS
1405;
1406        DB   'C'                ;CRT
1407        DB   'P'                ;PRINTER
1408        DB   'B'                ;BATCH= COMMANDS FROM READER
1409        DB   'U'                ;CUSE   USER
1410;
1411;
1412        DB   'R'                ;READER ASSIGNMENTS
1413;
1414        DB   'D'                ;DATA TRANSFER DEVICE
1415        DB   'P'                ;PRINTER
1416        DB   'A'                ;ALTERNATE (PARALLEL)
1417        DB   'U'                ;RUSER  USER
1418;
1419;
1420        DB   'P'                ;PUNCH ASSIGNMENTS
1421;
1422        DB   'D'                ;DATA TRANSFER DEVICE
1423        DB   'P'                ;PRINTER
1424        DB   'A'                ;ALTERNATE (PARALLEL)
1425        DB   'U'                ;PUSER  USER
1426;
1427;
1428        DB   'L'                ;LIST ASSIGNMENTS
1429;
1430        DB   'C'                ;CRT
1431        DB   'P'                ;PRINTER
1432        DB   'D'                ;DATA TRANSFER DEVICE
1433        DB   'U'                ;LUSER  USER
1434;
1435EXIT:
1436        POP  D
1437        POP  B
1438        POP  PSW
1439        POP  H
1440        SPHL
1441        NOP                     ;COULD BE EI
1442        LXI  H,0
1443HLX     EQU  $-2
1444        JMP  0
1445PCX     EQU  $-2
1446T1A:    DW   0
1447        DB   0
1448        DW   0
1449        DB   0
1450QIO:
1451        IN   0
1452        RET
1453;
1454ENDX:
1455;
1456ALOC    EQU  7
1457BLOC    EQU  5
1458CLOC    EQU  4
1459DLOC    EQU  3
1460ELOC    EQU  2
1461FLOC    EQU  6
1462HLOC    EQU  HLX-EXIT+11
1463LLOC    EQU  HLX-EXIT+8
1464PLOC    EQU  PCX-EXIT+11
1465SLOC    EQU  9
1466TLOC    EQU  T1A-EXIT+8
1467TLOCX   EQU  TLOC+2
1468QLOC    EQU  QIO-EXIT+11
1469;
1470ACTBL:
1471        DB   'A', ALOC
1472        DB   'B', BLOC
1473        DB   'C', CLOC
1474        DB   'D', DLOC
1475        DB   'E', ELOC
1476        DB   'F', FLOC
1477        DB   'H', HLOC
1478        DB   'L', LLOC+2
1479        DB   'M', HLOC OR 040H
1480        DB   'P', PLOC OR 080H
1481        DB   'S', SLOC OR 080H
1482;
1483ACTSZ   EQU  ($-ACTBL)/2
1484;
1485        DB   -1                 ;TABLE DELIMITER
1486;
1487        DB   'RWA'              ;AUTHOR
1488;       DB   '(C) 1979 ECT'
1489;
1490Z:                              ;END OF PROGRAM
1491;
1492;
1493        END
1494