11
2 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
3+                                                      19:09  05/27/2017
4+                                                                                      PAGE 1
5
6
7
8                   ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
9                   ;
10                   ; CUTER - MODIFIED TO USE MITS CARDS IN ALTAIR 8800
11                   ;
12                   ; PSEUDO DEVICE 0, CONSOLE: VDM-1 AT C8/CC00, KBD AT 4/5
13                   ; PSEUDO DEVICE 1, SERIAL:  MITS SIO REV. 1 AT 0/1
14                   ; PSEUDO DEVICE 2, SERIAL:  MITS 2SIO CHANNEL B AT 18/19
15                   ;
16                   ; TAPE I/O MODIFIED TO USE MITS ACR SIO AT 6/7
17                   ;
18                   ; 03/02/2017 UDO MUNK    FIRST VERSION FOR RELEASE
19                   ; 03/23/2017 UDO MUNK    USE MITS 2SIO CHANNEL B FOR PSEUDO 2
20                   ; 03/27/2017 UDO MUNK    USE MITS ACR SIO FOR TAPE I/O
21                   ; 06/27/2017 UDO MUNK    DON'T CLEAR TO EOL FOR CR, JUST ADVANCE LINE
22                   ;
23                   ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
24                   ;
25                   ;
26                   ;
27                   ;        CUTER(TM)
28                   ;
29                   ;                 COPYRIGHT (C) 1977
30                   ;                 SOFTWARE TECHNOLOGY CORP.
31                   ;                 P.O. BOX 5260
32                   ;                 SAN MATEO, CA 94402
33                   ;                 (415) 349-8080
34                   ;
35                   ;    A L L    R I G H T S   R E S E R V E D ! ! !
36                   ;
37                   ;
38                   ;        VERSION  1.3
39                   ;                 77-03-27
40                   ;
41                   ;
42                   ;  THIS PROGRAM IS DESIGNED TO BE A STANDALONE CUTS
43                   ;  OPERATING SYSTEM. CUTER IS DESIGNED TO BE READ IN FROM
44                   ;  CASSETTE TAPE OR TO BE RESIDENT IN READ-ONLY-MEMORY.
45                   ;  CUTER SUPPORTS VARIOUS DEVICES INCLUDING SERIAL,
46                   ;  PARALLEL, THE PROCESSOR TECHNOLOGY VDM(TM) AND UP TO
47                   ;  TWO CUTS TAPE DRIVES.
48                   ;
49                   ;  CUTER(TM) HAS BEEN WRITTEN SO AS TO BE COMPATIBLE WITH
50                   ;  SOLOS(TM).  THE FOLLOWING KEYS ARE USED BY CUTER(TM)
51                   ;  IN PLACE OF THE SPECIAL KEYS ON THE SOL KEYBOARD:
52                   ;
53                   ;     CURSOR UP       CTL-W
54                   ;     CURSOR LEFT     CTL-A
55                   ;     CURSOR RIGHT    CTL-S
56                   ;     CURSOR DOWN     CTL-Z
57                   ;     CURSOR HOME     CTL-N
58                   ;     CLEAR SCREEN    CTL-K
591
60 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
61+                                                      19:09  05/27/2017
62+                                                                                      PAGE 2
63
64
65
66                   ;     MODE            CTL-@
67                   ;
68                   ;
69                   ;
70   C000                    ORG     0C000H
71                   ;
72                   ;
73                   ;   AUTO-STARTUP CODE
74                   ;
75   C000   7F       START:  MOV     A,A     ;SHOW THIS IS CUTER (SOLOS=00)
76                   ;      THIS BYTE ALLOWS AUTOMATIC POWER ON ENTRY
77                   ;      WHEN IN ROM SUPPORTING THIS HARDWARE FEATURE.
78   C001   C3D7C1   INIT:   JMP     STRTA   ;SYSTEM RESTART ENTRY POINT
79                   ;
80                   ;   THESE JUMP POINTS ARE PROVIDED TO ALLOW COMMON ENTRY
81                   ; LOCATIONS FOR ALL VERSIONS OF CUTER.  THEY ARE USED
82                   ; EXTENSIVELY BY CUTS SYSTEM PROGRAMS AND IT IS RECOMMENDED
83                   ; THAT USER ROUTINES ACCESS CUTER ROUTINES THROUGH THESE
84                   ; POINTS ONLY!
85                   ;
86   C004   C318C2   RETRN:  JMP     COMND   ;RETURN TO CUTER COMMAND PROCESSOR
87   C007   C3DCC5   FOPEN:  JMP     BOPEN   ;CASSETTE OPEN FILE ENTRY
88   C00A   C3FFC5   FCLOS:  JMP     PCLOS   ;CASSETTE CLOSE FILE ENTRY
89   C00D   C342C6   RDBYT:  JMP     RTBYT   ;CASSETTE READ BYTE ENTRY
90   C010   C37FC6   WRBYT:  JMP     WTBYT   ;CASSETTE WRITE BYTE ENTRY
91   C013   C3C7C6   RDBLK:  JMP     RTAPE   ;CASSETTE READ BLOCK ENTRY
92   C016   C37CC7   WRBLK:  JMP     WTAPE   ;CASSETTE WRITE BLOCK ENTRY
93                   ;
94                   ;     SYSTEM I/O ENTRY POINTS
95                   ;
96                   ;  THESE FOUR ENTRY POINTS ARE USED TO EITHER INPUT
97                   ;  OR OUTPUT TO CUTER PSUEDO PORTS.
98                   ;  THESE PSUEDO PORTS ARE AS FOLLOWS:
99                   ;
100                   ;  PORT   INPUT              OUTPUT
101                   ;  ----   -----------------  ---------------------
102                   ;   0     KEYBOARD INPUT     BUILT-IN VDM DRIVER
103                   ;         ACTUAL PORT 3      PORT C8, MEMORY FROM CC00
104                   ;   1     SERIAL PORT        SERIAL PORT
105                   ;         ACTUAL PORT 1      ACTUAL PORT 1
106                   ;   2     PARALLEL PORT      PARALLEL PORT
107                   ;         ACTUAL PORT 2      ACTUAL PORT 2
108                   ;   3     USER'S INPUT RTN   USER'S OUTPUT ROUTINE
109                   ;
110                   ;  STATUS FOR ACTUAL PORTS 1, 2 AND 3 IS VIA ACTUAL
111                   ;  PORT 0.  THE BITS OF PORT ZERO ARE DEFINED AS FOLLOWS:
112                   ;
113                   ;   :     :     :     :     :     :---- : --- : --- :
114                   ;   : TBE : RDA :     :     :     :PXDR : PDR : KDR :
115                   ; BIT  7     6     5     4     3     2     1     0
116                   ;
1171
118 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
119+                                                      19:09  05/27/2017
120+                                                                                      PAGE 3
121
122
123
124                   ;  WHERE:
125                   ;    TBE    1=TRANSMITTER BUFFER EMPTY (SERIAL)
126                   ;    RDA    1=READER DATA AVAILABLE (SERIAL)
127                   ;    ----
128                   ;    PXDR   0=PARALLEL EXTERNAL DEVICE READY
129                   ;    ---
130                   ;    PDR    0=PARALLEL DATA READY
131                   ;    ---
132                   ;    KDR    0=KEYBOARD DATA READY
133                   ;
134                   ;
135                   ;
136                   ;
137                   ;  NOTE: SOUT AND SINP ARE "LDA" INSTRUCTIONS.
138                   ;        THIS FACT IS USED TO ALLOW ACCESS TO THE
139                   ;        BYTES "OPORT" AND "IPORT" DYNAMICALLY.
140                   ;        THESE MUST REMAIN "LDA" INSTRUCTIONS!!!!!
141                   ;
142   C019   3A07C8   SOUT:   LDA     OPORT   ;OUTPUT VIA STANDARD OUTPUT PSUEDO PORT
143   C01C   C32EC0   AOUT:   JMP     OUTPR   ;OUTPUT VIA PSUEDO PORT SPECIFIED IN REG A
144   C01F   3A06C8   SINP:   LDA     IPORT   ;INPUT VIA STANDARD INPUT PSUEDO PORT
145   C022            AINP    EQU     $       ;INPUT VIA PSUEDO PORT SPECIFIED IN REG A
146                   ; -----------END OF SYSTEM ENTRY POINTS----------
147                   ;
148                   ;
149                   ; AINP CONTINUES HERE (IT COULD HAVE BEEN A "JMP" THOUGH)
150   C022   E5               PUSH    H       ;SAVE HL FM ENTRY
151   C023   2109C3           LXI     H,ITAB
152                   ;
153                   ;    THIS ROUTINE PROCESSES THE I/O REQUESTS
154                   ;
155   C026   E603     IOPRC:  ANI     3       ;KEEP REGISTER "A" TO FOUR VALUES
156   C028   07               RLC             ;COMPUTE ENTRY ADDRESS
157   C029   85               ADD     L
158   C02A   6F               MOV     L,A     ;WE HAVE ADDRESS
159   C02B   C387C2           JMP     DISPT   ;DISPATCH TO IT
160                   ;
161                   ;
162   C02E            OUTPR   EQU     $       ;PROCESS OUTPUT REQUESTS
163   C02E   E5               PUSH    H       ;SAVE REGS
164   C02F   2101C3           LXI     H,OTAB  ;POINT TO OUTPUT DISPATCH TABLE
165   C032   C326C0           JMP     IOPRC   ;DISPATCH FOR PROPER PSUEDO PORT
166                   ;
167                   ;
168                   ;
169                   ; CUTER SYSTEM I/O ROUTINES
170                   ;
171                   ;
172                   ;    THIS ROUTINE IS A MODEL OF ALL INPUT ROUTINES WITHIN
173                   ;  CUTER.  THE FIRST ROUTINE "KREA1" PERFORMS THE INPUT
174                   ;  FROM THE STANDARD KEYBOARD ON PARALLEL PORT 3.
1751
176 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
177+                                                      19:09  05/27/2017
178+                                                                                      PAGE 4
179
180
181
182                   ;  ALL STANDARD INPUT DRIVERS RETURN EITHER THE CHARACTER
183                   ;  WITH A NON-ZERO FLAG, OR JUST A ZERO FLAG INDICATING
184                   ;  THAT NO CHARACTER IS AVAILABLE YET.  IT WILL BE THE
185                   ;  RESPONSIBILITY OF THE USER TO LOOP WAITING FOR A
186                   ;  CHARACTER, OR TO USE THE INPUT AS A STATUS REQUEST.
187                   ;  WHEN A CHARACTER IS AVAILABLE, IT IS RETURNED IN REG A.
188                   ;
189                   ;  THE FOLLOWING KEYBOARD ROUTINE MAY BE USED AS A SAMPLE
190                   ;  OF HOW TO WRITE A USER INPUT ROUTINE.
191                   ;
192                   ;         KEYBOARD INPUT ROUTINE
193                   ;
194                   ; MODIFIED SO THAT KBD STATUS PORT CAN BE DIFFERENT FROM SIO STATUS PORT
195                   ; UDO MUNK
196                   ;
197   C035            KREA1   EQU     $       ;KEYBOARD READ ROUTINE
198                   ;       IN      STAPT   ;GET STATUS WORD
199   C035   DB04             IN      STKBD   ;*UM*
200   C037   2F               CMA             ;INVERT IT FOR PROPER RETURN
201   C038   E601             ANI     KDR     ;TEST NOT KEYBOARD DATA READY
202   C03A   C8               RZ              ;ZERO IF NO CHARACTER RECEIVED
203                   ;
204   C03B   DB05             IN      KDATA   ;GET CHARACTER
205   C03D   C9               RET             ;GO BACK WITH IT
206                   ;
207                   ;
208                   ;
209                   ;   SERIAL INPUT ROUTINE
210                   ;
211   C03E            SREA1   EQU     $       ;SERIAL INPUT ROUTINE
212   C03E   DB00             IN      STAPT   ;GET STATUS
213   C040   2F               CMA             ;*UM* MITS SIO FLAGS ARE ACTIVE LOW
214   C041   E601             ANI     SDR     ;TEST FOR SERIAL DATA READY
215   C043   C8               RZ              ;FLAGS ARE SET
216                   ;
217   C044   DB01             IN      SDATA   ;GET DATA BYTE
218                   ;  IT IS UP TO THE CALLER TO STRIP PARITY IF DESIRED
219   C046   C9               RET             ;WE HAVE IT
220                   ;
221                   ;
222                   ;   SERIAL DATA OUTPUT
223                   ;
224                   ; MODIFIED SO THAT STATUS BIT CAN BE DEFINED AS ANY BIT
225                   ; UDO MUNK
226                   ;
227   C047            SEROT   EQU     $       ;SERIAL OUTPUT ROUTINE
228   C047   DB00             IN      STAPT   ;GET STATUS
229                   ;        RAL             ;PUT HIGH BIT IN CARRY
230                   ;        JNC     SEROT   ;LOOP UNTIL TRANSMITTER BUFFER IS EMPTY
231   C049   E680             ANI     STBE    ;*UM*
232   C04B   C247C0           JNZ     SEROT   ;*UM*
2331
234 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
235+                                                      19:09  05/27/2017
236+                                                                                      PAGE 5
237
238
239
240   C04E   78               MOV     A,B     ;GET THE CHARACTER BACK
241   C04F   D301             OUT     SDATA   ;SEND IT OUT
242   C051   C9               RET             ;AND WE'RE DONE
243                   ;
244                   ;
245                   ; PARALLEL DATA INPUT
246                   ;
247                   ; MODIFIED TO USE 2SIO CHANNEL B
248                   ; UDO MUNK
249                   ;
250   C052            PARIT   EQU     $       ;GET CHAR FM PARALLEL PORT
251                   ;        IN      STAPT   ;STATUS
252                   ;        CMA             ;INVERT FOR PROPER RETURN
253                   ;        ANI     PDR     ;IS DATA READY?
254                   ;        RZ              ;NO--JUST EXIT
255                   ;        IN      PDATA   ;YES--GET CHAR THEN
256                   ;        RET             ;THEN EXIT
257   C052   DB12             IN      SIO2S   ;GET STATUS
258   C054   E601             ANI     SDR2    ;TEST FOR SERIAL DATA READY
259   C056   C8               RZ              ;FLAGS ARE SET
260   C057   DB13             IN      SIO2D   ;GET DATA BYTE
261   C059   C9               RET             ;WE HAVE IT
262                   ;
263                   ;
264                   ;  PARALLEL DATA OUTPUT ROUTINE
265                   ;
266                   ; MODIFIED TO USE 2SIO CHANNEL B
267                   ; UDO MUNK
268                   ;
269   C05A            PAROT   EQU     $       ;OUTPUT CHAR TO PARALLEL PORT
270                   ;        IN      STAPT   ;STATUS
271                   ;        ANI     PXDR    ;IS EXTERNAL DEVICE READY?
272                   ;        JNZ     PAROT   ;NO--WAIT TIL IT IS
273                   ;        MOV     A,B     ;GET CHAR
274                   ;        OUT     PDATA   ;SEND DATA NOW
275                   ;        RET             ;DONE
276   C05A   DB12             IN      SIO2S   ;GET STATUS
277   C05C   E602             ANI     STBE2   ;DEVICE READY ?
278   C05E   CA5AC0           JZ      PAROT   ;NO, WAIT
279   C061   78               MOV     A,B     ;GET THE CHARACTER BACK
280   C062   D313             OUT     SIO2D   ;SEND IT OUT
281   C064   C9               RET             ;AND WE'RE DONE
282                   ;
283                   ;
284                   ; USER DEFINED INPUT/OUTPUT ROUTINES
285   C065            ERRIT   EQU     $       ;USER INPUT ROUTINE
286   C065   E5               PUSH    H       ;SAVE ORIG HL
287   C066   2A00C8           LHLD    UIPRT   ;GET USER'S RTN ADDR
288   C069   C370C0           JMP     ERRO1   ;MERGE TO VERIFY THE ADDR
289                   ;
290   C06C            ERROT   EQU     $       ;USER OUTPUT ROUTINE
2911
292 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
293+                                                      19:09  05/27/2017
294+                                                                                      PAGE 6
295
296
297
298   C06C   E5               PUSH    H       ;SAVE ORIG HL
299   C06D   2A02C8           LHLD    UOPRT   ;GET USER'S RTN ADDR
300   C070            ERRO1   EQU     $       ;WE MERGE HERE TO VFY ADDR
301   C070   7D               MOV     A,L     ;ZERO=UNDEFINED
302   C071   B4               ORA     H       ;IS IT?
303   C072   C28BC2           JNZ     DISP1   ;NO--VALID--OFF TO IT
304   C075   C30FC2           JMP     STRTD   ;RESET I/O PORTS AND BACK TO COMMAND MODE
305                   ;
306                   ;
307                   ;
308                   ;                  VIDEO DISPLAY ROUTINES
309                   ;
310                   ;
311                   ;  THESE ROUTINES ALLOW FOR STANDARD VIDEO TERMINAL
312                   ;  OPERATIONS.  ON ENTRY, THE CHARACTER FOR OUTPUT IS IN
313                   ;  REGISTER B AND ALL REGISTERS ARE UNALTERED ON RETURN.
314                   ;
315                   ;
316                   ;
317   C078            VDM01   EQU     $       ;VDM OUTPUT DRIVER
318   C078   E5               PUSH    H       ;SAVE HL
319   C079   D5               PUSH    D       ;SAVE DE
320   C07A   C5               PUSH    B
321                   ;
322                   ;  PROCESS ESC SEQUENCE IF ANY
323                   ;
324   C07B   3A0CC8           LDA     ESCFL   ;GET ESCAPE FLAG
325   C07E   B7               ORA     A
326   C07F   C287C1           JNZ     ESCS    ;IF NON ZERO GO PROCESS THE REST OF THE SEQUENCE
327                   ;
328   C082   78               MOV     A,B     ;GET CHAR
329   C083   E67F             ANI     7FH     ;CLR HI BIT IN CASE
330   C085   47               MOV     B,A     ;USE CHAR STRIPPED OF HI BIT FOR COMPATABILITY
331   C086   CAA0C0           JZ      GOBK    ;MAKE A QUICK EXIT FOR A NULL
332                   ;
333   C089   21E2C2           LXI     H,TBL
334   C08C   CDA6C0           CALL    TSRCH   ;GO PROCESS
335                   ;
336   C08F            GOBACK  EQU     $       ;RESET CURSOR AND DELAY
337   C08F   CD45C1           CALL    VDADD   ;GET SCRN ADDR
338   C092   7E               MOV     A,M     ;GET CHAR
339   C093   F680             ORI     80H     ;INVERSE VIDEO
340   C095   77               MOV     M,A     ;CURSOR IS NOW THERE
341   C096   2A0AC8           LHLD    SPEED-1 ;GET DELAY SPEED
342   C099   2C               INR     L       ;MAKE IT DEFINITELY NON-ZERO
343   C09A   AF               XRA     A       ;DELAY ENDS WHEN H=ZERO
344   C09B   2B       TIMER:  DCX     H       ;LOOP FOR DELAY AMNT
345   C09C   BC               CMP     H       ;IS IT DONE YET
346   C09D   C29BC0           JNZ     TIMER   ;NO--KEEP DELAYING
347   C0A0   C1       GOBK:   POP     B
348   C0A1   D1               POP     D       ;RESTORE ALL REGISTERS
3491
350 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
351+                                                      19:09  05/27/2017
352+                                                                                      PAGE 7
353
354
355
356   C0A2   E1               POP     H
357   C0A3   C9               RET             ;EXIT FROM VDMOT
358                   ;
359                   ;
360   C0A4            NEXT    EQU     $       ;GO TO NEXT CHR
361   C0A4   23               INX     H
362   C0A5   23               INX     H
363                   ;
364                   ;  THIS ROUTINE SEARCHES FOR A MATCH OF THE CHAR IN "B"
365                   ;  TO THE CHAR IN THE TBL POINTED TO BY HL.
366                   ;
367   C0A6   7E       TSRCH:  MOV     A,M     ;GET CHR FROM TABLE
368   C0A7   B7               ORA     A       ;SEE IF END OF TBL
369   C0A8   CAB8C0           JZ      CHAR    ;ZERO IS THE LAST
370   C0AB   B8               CMP     B       ;TEST THE CHR
371   C0AC   23               INX     H       ;POINT FORWARD
372   C0AD   C2A4C0           JNZ     NEXT
373   C0B0   E5               PUSH    H       ;FOUND ONE...SAVE ADDRESS
374   C0B1   CD5FC1           CALL    CREM    ;REMOVE CURSOR
375   C0B4   E3               XTHL            ;RESTORE ADDR OF CHAR ENTRY IN TBL
376   C0B5   C387C2           JMP     DISPT   ;DISPATCH FOR CURSOR CONTROL
377                   ;
378                   ;
379   C0B8            CHAR    EQU     $       ;WE HAVE A CHAR
380   C0B8   78               MOV     A,B     ;GET CHARACTER
381   C0B9   FE7F             CPI     7FH     ;IS IT A DEL?
382   C0BB   C8               RZ              ;GO BACK IF SO
383                   ;
384                   ;
385                   ;
386   C0BC   CD45C1   OCHAR:  CALL    VDADD   ;GET SCREEN ADDRESS
387   C0BF   70               MOV     M,B     ;PUT CHR ON SCREEN
388   C0C0   3A08C8           LDA     NCHAR   ;GET CHARACTER POSITION
389   C0C3   FE3F             CPI     63      ;END OF LINE?
390   C0C5   DAE5C0           JC      OK
391   C0C8   3A09C8           LDA     LINE
392   C0CB   FE0F             CPI     15      ;END OF SCREEN?
393   C0CD   C2E5C0           JNZ     OK
394                   ;
395                   ;   END OF SCREEN...ROLL UP ONE LINE
396                   ;
397   C0D0   AF       SCROLL: XRA     A
398   C0D1   3208C8           STA     NCHAR   ;BACK TO FIRST CHAR POSITION
399   C0D4   4F       SROL:   MOV     C,A
400   C0D5   CD4CC1           CALL    VDAD    ;CALCULATE LINE TO BE BLANKED
401   C0D8   AF               XRA     A
402   C0D9   CD23C1           CALL    CLIN1   ;CLEAR IT
403   C0DC   3A0AC8           LDA     BOT
404   C0DF   3C               INR     A
405   C0E0   E60F             ANI     0FH
406   C0E2   C312C1           JMP     ERAS3
4071
408 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
409+                                                      19:09  05/27/2017
410+                                                                                      PAGE 8
411
412
413
414                   ;
415                   ;   INCREMENT LINE COUNTER IF NECESSARY
416                   ;
417   C0E5   3A08C8   OK:     LDA     NCHAR   ;GET CHR POSITION
418   C0E8   3C               INR     A
419   C0E9   E63F             ANI     3FH     ;MOD 64
420   C0EB   3208C8           STA     NCHAR   ;STORE THE NEW
421   C0EE   C0               RNZ             ;MORE CHARS THIS LINE
422   C0EF            PDOWN   EQU     $       ;MOVE CURSOR DOWN ONE LINE
423   C0EF   3A09C8           LDA     LINE    ;GET THE LINE COUNT
424   C0F2   3C               INR     A
425   C0F3   E60F     CURSC:  ANI     0FH     ;MOD 15 INCREMENT
426   C0F5   3209C8   CUR:    STA     LINE    ;STORE THE NEW
427   C0F8   C9               RET
428                   ;
429                   ;    ERASE SCREEN
430                   ;
431   C0F9   2100CC   PERSE:  LXI     H,VDMEM ;POINT TO SCREEN
432   C0FC   36A0             MVI     M,80H+' ' ;THIS IS THE CURSOR
433                   ;
434   C0FE   23               INX     H       ;NEXT CHAR
435   C0FF            ERAS1   EQU     $       ;LOOP TO CLR SCRN
436   C0FF   3620             MVI     M,' '   ;BLANK IT OUT
437   C101   23               INX     H       ;NEXT SCRN LOC
438   C102   7C               MOV     A,H     ;SEE IF DONE
439   C103   FED0             CPI     0D0H    ;DID IT GO ABOVE VDM
440   C105   DAFFC0           JC      ERAS1   ;NO--MORE
441   C108   37               STC             ;SAY WE WANT TO DROP THRU TO ERAS3
442                   ;
443   C109            PHOME   EQU     $       ;RESET CURSOR TO HOME
444   C109   3E00             MVI     A,0     ;CLEAR, LEAVE CARRY AS IS
445   C10B   3209C8           STA     LINE    ;ZERO LINE
446   C10E   3208C8           STA     NCHAR   ;LEFT SIDE OF SCREEN
447   C111   D0               RNC             ;THIS IS JUST A HOME OPERATION
448                   ;
449   C112   D3C8     ERAS3:  OUT     DSTAT   ;RESET SCROLL PARAMETERS
450   C114   320AC8           STA     BOT     ;BEGINNING OF TEXT OFFSET
451   C117   C9               RET
452                   ;
453                   ;
454   C118            CLIN2   EQU     $       ;HERE TO SEE IF VDM OUTPUT
455   C118   3A07C8           LDA     OPORT   ;GET CRNT OUTPUT PORT
456   C11B   B7               ORA     A
457   C11C   C0               RNZ             ;NOT VDM--DONE THEN
458   C11D   CD45C1   CLINE:  CALL    VDADD   ;GET CURRENT SCREEN ADDRESS
459   C120   3A08C8           LDA     NCHAR   ;CURRENT CURSOR POSITION
460   C123   FE40     CLIN1:  CPI     64      ;NO MORE THAN 63
461   C125   D0               RNC             ;ALL DONE
462   C126   3620             MVI     M,' '   ;ALL SPACED OUT
463   C128   23               INX     H
464   C129   3C               INR     A
4651
466 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
467+                                                      19:09  05/27/2017
468+                                                                                      PAGE 9
469
470
471
472   C12A   C323C1           JMP     CLIN1   ;LOOP TO END OF LINE
473                   ;
474                   ;
475                   ;  ROUTINE TO MOVE THE CURSOR UP ONE LINE
476                   ;
477   C12D   3A09C8   PUP:    LDA     LINE    ;GET LINE COUNT
478   C130   3D               DCR     A
479   C131   C3F3C0           JMP     CURSC   ;MERGE
480                   ;
481                   ;  MOVE CURSOR LEFT ONE POSITION
482                   ;
483   C134   3A08C8   PLEFT:  LDA     NCHAR
484   C137   3D               DCR     A
485   C138            PCUR    EQU     $       ;TAKE CARE OF CURSOR SAME LINE
486   C138   E63F             ANI     03FH    ;LET CURSOR WRAP AROUND
487   C13A   3208C8           STA     NCHAR   ;UPDATED CURSOR
488   C13D   C9               RET
489                   ;
490                   ;     CURSOR RIGHT ONE POSITION
491                   ;
492   C13E   3A08C8   PRIT:   LDA     NCHAR
493   C141   3C               INR     A
494   C142   C338C1           JMP     PCUR
495                   ;
496                   ;   ROUTINE TO CALCULATE SCREEN ADDRESS
497                   ;
498                   ;   ENTRY AT:    RETURNS:
499                   ;
500                   ;         VDADD  CURRENT SCREEN ADDRESS
501                   ;         VDAD2  ADDRESS OF CURRENT LINE, CHAR 'C'
502                   ;         VDAD   LINE 'A', CHARACTER POSITION 'C'
503
504   C145   3A08C8   VDADD:  LDA     NCHAR   ;GET CHARACTER POSITION
505   C148   4F               MOV     C,A     ;'C' KEEPS IT
506   C149   3A09C8   VDAD2:  LDA     LINE    ;LINE POSITION
507   C14C   6F       VDAD:   MOV     L,A     ;INTO 'L'
508   C14D   3A0AC8           LDA     BOT     ;GET TEXT OFFSET
509   C150   85               ADD     L       ;ADD IT TO THE LINE POSITION
510   C151   0F               RRC             ;TIMES TWO
511   C152   0F               RRC             ;MAKES FOUR
512   C153   6F               MOV     L,A     ;L HAS IT
513   C154   E603             ANI     3       ;MOD THREE FOR LATER
514   C156   C6CC             ADI     VDMEM SHR 8 ;LOW SCREEN OFFSET
515   C158   67               MOV     H,A     ;NOW H IS DONE
516   C159   7D               MOV     A,L     ;TWIST L'S ARM
517   C15A   E6C0             ANI     0C0H
518   C15C   81               ADD     C
519   C15D   6F               MOV     L,A
520   C15E   C9               RET             ;H & L ARE NOW PERVERTED
521                   ;
522                   ;    ROUTINE TO REMOVE CURSOR
5231
524 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
525+                                                      19:09  05/27/2017
526+                                                                                      PAGE 10
527
528
529
530                   ;
531   C15F   CD45C1   CREM:   CALL    VDADD   ;GET CURRENT SCREEN ADDRESS
532   C162   7E               MOV     A,M
533   C163   E67F             ANI     7FH     ;STRIP OFF THE CURSOR
534   C165   77               MOV     M,A
535   C166   C9               RET
536                   ;
537                   ;     ROUTINE TO BACKSPACE
538                   ;
539   C167   CD34C1   PBACK:  CALL    PLEFT
540   C16A   CD45C1           CALL    VDADD   ;GET SCREEN ADDRESS
541   C16D   3620             MVI     M,' '   ;PUT A BLANK THERE
542   C16F   C9               RET
543                   ;
544                   ;     ROUTINE TO PROCESS A CARRIAGE RETURN
545                   ;
546   C170            PCR:    ;CALL    CLINE   ;CLEAR FROM CURRENT CURSOR TO END OF LINE
547                   ;  NOTE THAT A COMES BACK=64 WHICH WILL BE CLEARED AT PCUR
548   C170   3E40             MVI     A,64    ;*UM* JUST ADVANCE LINE
549   C172   C338C1           JMP     PCUR    ;AND STORE THE NEW VALUE
550                   ;
551                   ;   ROUTINE TO PROCESS LINEFEED
552                   ;
553   C175   3A09C8   PLF:    LDA     LINE    ;GET LINE COUNT
554   C178   3C               INR     A       ;NEXT LINE
555   C179   E60F             ANI     15      ;SEE IF IT WRAPPED AROUND
556   C17B   C2F5C0           JNZ     CUR     ;IT DID NOT--NO SCROLL
557                   ;
558   C17E   C3D4C0           JMP     SROL    ;SCROLL ONE LINE--CURSOR SOME POSITION
559                   ;
560                   ;     SET ESCAPE PROCESS FLAG
561                   ;
562   C181   3EFF     PESC:   MVI     A,(-1) AND 0FFH
563   C183   320CC8           STA     ESCFL   ;SET FLAG
564   C186   C9               RET
565                   ;
566                   ;       PROCESS ESCAPE SEQUENCE
567                   ;
568   C187   CD5FC1   ESCS:   CALL    CREM    ;REMOVE CURSOR
569   C18A   CD90C1           CALL    ESCSP   ;PROCESS THE CHARACTER
570   C18D   C38FC0           JMP     GOBACK
571                   ;
572   C190   3A0CC8   ESCSP:  LDA     ESCFL   ;GET ESCAPE FLAG
573   C193   FEFF             CPI     (-1) AND 0FFH ;TEST FLAG
574   C195   CAB8C1           JZ      SECOND
575                   ;
576                   ;  PROCESS THIRD CHR OF ESC SEQUENCE
577                   ;
578   C198   210CC8           LXI     H,ESCFL
579   C19B   3600             MVI     M,0
580   C19D   FE02             CPI     2
5811
582 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
583+                                                      19:09  05/27/2017
584+                                                                                      PAGE 11
585
586
587
588   C19F   DAB0C1           JC      SETX    ;SET X
589   C1A2   CAB4C1           JZ      SETY    ;SET Y
590   C1A5   FE08             CPI     8       ;SPECIAL SET SPEED
591   C1A7   CA94C5           JZ      STSPD   ;YES--SET THE SPEED WITH IT THEN
592   C1AA   FE09             CPI     9
593   C1AC   DABCC0           JC      OCHAR   ;PUT IT ON THE SCREEN
594   C1AF   C0               RNZ
595                   ;
596                   ;  TAB ABSOLUTE TO VALUE IN REG B
597                   ;
598   C1B0   78       SETX:   MOV     A,B
599   C1B1   C338C1           JMP     PCUR
600                   ;
601                   ;  SET CURSOR TO LINE "B"
602                   ;
603   C1B4   78       SETY:   MOV     A,B
604   C1B5   C3F3C0           JMP     CURSC
605                   ;
606                   ;
607                   ;   PROCESS SECOND CHR OF ESC SEQUENCE
608                   ;
609   C1B8   78       SECOND: MOV     A,B
610   C1B9   FE03             CPI     3
611   C1BB   CACEC1           JZ      CURET
612   C1BE   FE04             CPI     4
613   C1C0   C2CAC1           JNZ     ARET2
614                   ;
615   C1C3   44       ARET:   MOV     B,H
616   C1C4   4D               MOV     C,L     ;PRESENT SCREEN ADDRESS TO BC FOR RETURN
617   C1C5   E1       ARET1:  POP     H       ;RETURN ADDRESS
618   C1C6   D1               POP     D       ;OLD B
619   C1C7   C5               PUSH    B
620   C1C8   E5               PUSH    H
621   C1C9   AF               XRA     A
622   C1CA   320CC8   ARET2:  STA     ESCFL
623   C1CD   C9               RET
624                   ;
625                   ;
626                   ;     RETURN PRESENT SCREEN PARAMETERS IN BC
627                   ;
628   C1CE   2108C8   CURET:  LXI     H,NCHAR
629   C1D1   46               MOV     B,M     ;CHARACTER POSITION
630   C1D2   23               INX     H
631   C1D3   4E               MOV     C,M     ;LINE POSITION
632   C1D4   C3C5C1           JMP     ARET1
633                   ;
634                   ;
635                   ;
636                   ;                START UP SYSTEM
637                   ;
638                   ;   CLEAR SCREEN AND THE FIRST 256 BYTES OF GLOBAL RAM
6391
640 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
641+                                                      19:09  05/27/2017
642+                                                                                      PAGE 12
643
644
645
646                   ;  THEN ENTER THE COMMAND MODE.
647                   ;
648   C1D7   AF       STRTA:  XRA     A
649   C1D8   4F               MOV     C,A
650   C1D9   2104C8           LXI     H,DFLTS ;CLEAR AFTER USER PORT ADDRESSES
651                   ;
652   C1DC   77       CLERA:  MOV     M,A
653   C1DD   23               INX     H
654   C1DE   0C               INR     C
655   C1DF   C2DCC1           JNZ     CLERA
656                   ;
657                   ; DETERMINE THE DEFAULT PORTS
658                   ;     THIS COULD BECOME "MVI A,XX" FOR YOUR SPECIFIC PORTS
659   C1E2   DBFF             IN      SENSE   ;GET SWITCHES
660                   ;
661   C1E4   47               MOV     B,A     ;SAVE IT
662   C1E5   E603             ANI     3       ;MAKE IT A VALID PORT
663   C1E7   3205C8           STA     DFLTS+1 ;SET DEFAULT OUTPUT PORT
664   C1EA   B7               ORA     A       ;SEE IF THIS THE VDM
665   C1EB   C2F4C1           JNZ     STRTB   ;NO--DO NOT RESET VDM
666   C1EE   31FFCB           LXI     SP,SYSTP ;SET UP THE STACK FOR CALL
667   C1F1   CDF9C0           CALL    PERSE   ;(REG A ASSUMED TO COME BACK ZERO)
668   C1F4            STRTB   EQU     $       ;FINISH OFF THIS PORT THEN DO NEXT
669   C1F4   210000           LXI     H,0     ;USE FOR CLEARING USER ADDRESSES
670   C1F7   FE03             CPI     3       ;IS IT A USER PORT
671   C1F9   CAFFC1           JZ      STRTC   ;YES-- DO NOT CLEAR IT
672   C1FC   2202C8           SHLD    UOPRT   ;NO--CLEAR ADDR
673   C1FF            STRTC   EQU     $       ;OUTPUT PORT ALL SET
674   C1FF   78               MOV     A,B     ;FM SENSE SWITCHES
675   C200   1F               RAR
676   C201   1F               RAR             ;NEXT 2 BITS ARE INPUT PORT
677   C202   E603             ANI     3       ;VALID PORT
678   C204   3204C8           STA     DFLTS   ;THIS IS DEFAULT INPUT PORT
679   C207   FE03             CPI     3       ;IS THIS ONE A USER PORT
680   C209   CA0FC2           JZ      STRTD   ;YES--DO NOT CLEAR IT THEN
681   C20C   2200C8           SHLD    UIPRT   ;NO--FORCE USER ADDRESS ZERO
682   C20F            STRTD   EQU     $       ;1ST TIME INITIALIZATION ALL DONE NOW
683   C20F   2A04C8           LHLD    DFLTS   ;PICK UP DEFAULT PORTS
684   C212   2206C8           SHLD    IPORT   ;FORCE PORTS TO DEFAULT
685   C215            COMN1   EQU     $       ;HERE TO TURN OFF TAPES, THEN COMMAND MODE
686   C215   AF               XRA     A
687   C216   D306             OUT     TAPPT   ;BE SURE TAPES ARE OFF
688                   ;
689                   ;
690                   ;
691                   ;            =--  COMMAND MODE  --=
692                   ;
693                   ;
694                   ;   THIS ROUTINE GETS AND PROCESSES COMMANDS
695                   ;
696   C218   31FFCB   COMND:  LXI     SP,SYSTP ;SET STACK POINTER
6971
698 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
699+                                                      19:09  05/27/2017
700+                                                                                      PAGE 13
701
702
703
704   C21B   CD3AC3           CALL    PROMPT  ;PUT PROMPT ON SCREEN
705   C21E   CD27C2           CALL    GCLI0   ;INIT TO GET COMMAND LINE
706   C221   CD6AC2           CALL    COPRC   ;PROCESS THE LINE
707   C224   C318C2           JMP     COMND   ;OVER AND OVER
708                   ;
709                   ;
710                   ;
711                   ;   THIS ROUTINE READS A COMMAND LINE FROM THE SYSTEM
712                   ;  KEYBOARD
713                   ;
714                   ;  C/R   TERMINATES THE SEQUENCE ERASING ALL CHARS TO THE
715                   ;        RIGHT OF THE CURSOR
716                   ;  L/F   TERMINATES THE SEQUENCE
717                   ;  ESC   RESETS TO COMMAND MODE.
718                   ;
719   C227            GCLI0   EQU     $       ;HERE TO INIT FOR GCLIN
720   C227   2163CA           LXI     H,INLIN-1 ;PT TO CHAR IN FRONT OF INPUT BFR
721   C22A   3607             MVI     M,7     ;MAKE SURE IT IS "BELL" TO KEEP FM DEL'ING TOO FAR
722   C22C   23               INX     H       ;NOW PT TO INPUT BFR
723   C22D   220EC8           SHLD    INPTR   ;SAVE AS STARTING PTR
724   C230   3E50             MVI     A,80    ;NUMBER OF CHARS IN LINE (MAX)
725   C232            GCLI1   EQU     $       ;LOOP TO BLANK OUT LINE BFR
726   C232   3620             MVI     M,' '   ;BLANKS
727   C234   23               INX     H       ;NEXT CHAR
728   C235   3D               DCR     A       ;FOR THIS COUNT
729   C236   C232C2           JNZ     GCLI1   ;ENTIRE LINE
730   C239   CD1FC0   GCLIN:  CALL    SINP    ;READ INPUT DEVICE
731   C23C   CA39C2           JZ      GCLIN
732   C23F   E67F             ANI     7FH     ;MAKE SURE NO X'80' BIT DURING CMND MODE
733   C241   CA0FC2           JZ      STRTD   ;IF EITHER MODE (OR CTL-@)
734   C244   47               MOV     B,A
735   C245   FE0D             CPI     CR      ;IS IT CR?
736   C247   CA18C1           JZ      CLIN2   ;YES--TERMINATE LINE HERE (CLR IF VDM)
737   C24A   FE0A             CPI     LF      ;IS IT A LINEFEED
738   C24C   C8               RZ              ;YES--TERMINATE LINE AS IS
739   C24D   2A0EC8           LHLD    INPTR   ;CRNT LINE PTR
740   C250   FE7F             CPI     7FH     ;DELETE CHR?
741   C252   C25FC2           JNZ     GCLI2   ;NO--OK
742   C255   0608             MVI     B,BACKS ;REPLACE IT
743   C257   2B               DCX     H       ;BACK LINE PTR UP TOO
744   C258   3E07             MVI     A,'G'-40H ;SEE IF A BELL
745   C25A   BE               CMP     M       ;IS IT?
746   C25B   C261C2           JNZ     GCLI3   ;NO--OK
747   C25E   47               MOV     B,A     ;YES--RING THE BELL THEN
748   C25F            GCLI2   EQU     $       ;STORE CHAR IN INPUT AREA
749   C25F   70               MOV     M,B     ;PLACE CHAR INTO LINE
750   C260   23               INX     H       ;NEXT CHAR
751   C261            GCLI3   EQU     $       ;SAVE NEW LINE PTR
752   C261   220EC8           SHLD    INPTR   ;SAVE PTR
753                   ;
754   C264   CD19C0   CONT:   CALL    SOUT
7551
756 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
757+                                                      19:09  05/27/2017
758+                                                                                      PAGE 14
759
760
761
762   C267   C339C2           JMP     GCLIN
763                   ;
764                   ;
765                   ;
766                   ;
767                   ;      FIND AND PROCESS COMMAND
768                   ;
769   C26A            COPRC   EQU     $       ;PROCESS THIS COMMAND LINE
770   C26A   CDAAC2           CALL    STUP    ;SETUP TO PROCESS INPUT LINE
771   C26D   EB               XCHG            ;DE=ADDR
772   C26E   2100C0           LXI     H,START ;PREP SO THAT HL WILL PT TO CUTER LATER
773   C271   E5               PUSH    H       ;PLACE PTR TO CUTER ON STACK FOR LATER DISPT
774   C272   CD6CC3           CALL    SCHR    ;SCAN PAST BLANKS
775   C275   CA6BC4           JZ      ERR1    ;NO COMMAND?
776   C278   EB               XCHG            ;HL HAS FIRST CHR
777   C279   11BDC2           LXI     D,COMTAB ;POINT TO COMMAND TABLE
778   C27C   CD91C2           CALL    FDCOM   ;SEE IF IN PRIMARY TABLE
779   C27F   CC8EC2           CZ      FDCOU   ;TRY CUSTOM ONLY IF NOT PRIMARY COMMAND
780   C282            DISP0   EQU     $       ;HERE TO EITHER DISPATCH OR DO ERROR
781   C282   CA6CC4           JZ      ERR2    ;NOT IN EITHER TABLE
782   C285   13               INX     D       ;PT DE TO ADDR OF RTN
783   C286   EB               XCHG            ;HL=ADDR OF ADDR OF RTN
784                   ; **** DROP THRU TO DISPT ***
785                   ;
786                   ; THIS ROUTINE DISPTACHES TO THE ADDR AT CONTENTS OF HL.
787                   ; HL ARE RESTORED PRIOR TO GOING TO ROUTINE.
788                   ;
789   C287            DISPT   EQU     $       ;DISPATCH
790   C287   7E               MOV     A,M     ;LOW BYTE
791   C288   23               INX     H
792   C289   66               MOV     H,M     ;HI BYTE
793   C28A   6F               MOV     L,A     ;AND LO, HL NOW COMPLETE
794   C28B            DISP1   EQU     $       ;HERE TO GO OFF TO HL DIRECTLY
795   C28B   E3               XTHL            ;HL RESTORED AND ADDR ON STACK
796   C28C   7D               MOV     A,L     ;ALWAYS PASS L IN "A" (PRIMARILY FOR SET'S)
797   C28D   C9               RET             ;OFF TO ROUTINE
798                   ;
799                   ;
800                   ;
801                   ;   THIS ROUTINE SEARCHES THROUGH A TABLE, POINTED TO
802                   ;  BY 'DE', FOR A DOUBLE CHARACTER MATCH OF THE 'HL'
803                   ;  MEMORY CONTENT.  IF NO MATCH IS FOUND THE SCAN ENDS
804                   ;  WITH THE ZERO FLAG SET, ELSE NON-ZERO SET.
805                   ;
806   C28E            FDCOU   EQU     $       ;HERE TO SCAN CUSTOM TABLE
807   C28E   113CC8           LXI     D,CUTAB ;PT TO CUSTOM RTN TBL
808   C291   1A       FDCOM:  LDAX    D
809   C292   B7               ORA     A       ;TEST FOR TABLE END
810   C293   C8               RZ              ;NOT FOUND POST THAT AND RETURN
811   C294   E5               PUSH    H       ;SAVE START OF SCAN ADDRESS
812   C295   BE               CMP     M       ;TEST FIRST CHR
8131
814 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
815+                                                      19:09  05/27/2017
816+                                                                                      PAGE 15
817
818
819
820   C296   13               INX     D
821   C297   C2A3C2           JNZ     NCOM
822                   ;
823   C29A   23               INX     H
824   C29B   1A               LDAX    D
825   C29C   BE               CMP     M       ;NOW SECOND CHARACTER
826   C29D   C2A3C2           JNZ     NCOM    ;GOODNESS
827                   ;
828   C2A0   E1               POP     H       ;RETURN HL TO PT TO CHAR START
829   C2A1   B7               ORA     A       ;FORCE TO NON-ZERO FLAG
830   C2A2   C9               RET             ;LET CALLER KNOW
831                   ;
832                   ;
833   C2A3   13       NCOM:   INX     D       ;GO TO NEXT ENTRY
834   C2A4   13               INX     D
835   C2A5   13               INX     D
836   C2A6   E1               POP     H       ;GET BACK ORIGINAL ADDRESS
837   C2A7   C391C2           JMP     FDCOM   ;CONTINUE SEARCH
838                   ;
839                   ;
840                   ; SET UP TO PROCESS AN INPUT LINE
841   C2AA            STUP    EQU     $       ;PREPARE WHETHER VDM OR NOT
842   C2AA   2164CA           LXI     H,INLIN ;ASSUME NON-VDM INPUT
843   C2AD   220EC8           SHLD    INPTR   ;ALSO RESET PTR FOR NOW
844   C2B0   3A07C8           LDA     OPORT   ;SEE IF IT IS VDM
845   C2B3   B7               ORA     A       ;IS IT THE VDM PORT
846   C2B4   C0               RNZ             ;NO--HL ARE SET PROPERLY
847   C2B5   CD5FC1           CALL    CREM    ;REMOVE CURSOR
848   C2B8   0E01             MVI     C,1     ;GET VDM ADDR FM POSITION ONE
849   C2BA   C349C1           JMP     VDAD2   ;GET SCRN ADDR
850                   ;
851                   ;           COMMAND TABLE
852                   ;
853                   ;  THIS TABLE DESCRIBES THE VALID COMMANDS FOR CUTER
854                   ;
855   C2BD            COMTAB  EQU     $       ;START OF KNOWN COMMANDS
856   C2BD   4455             DB      'DU'    ;DUMP
857   C2BF   ADC3             DW      DUMP
858   C2C1   454E             DB      'EN'    ;ENTR
859   C2C3   14C4             DW      ENTER
860   C2C5   4558             DB      'EX'    ;EXEC
861   C2C7   49C4             DW      EXEC
862   C2C9   4745             DB      'GE'    ;GET
863   C2CB   A1C4             DW      TLOAD
864   C2CD   5341             DB      'SA'    ;SAVE
865   C2CF   E0C4             DW      TSAVE
866   C2D1   5845             DB      'XE'    ;XEQ
867   C2D3   A0C4             DW      TXEQ
868   C2D5   4341             DB      'CA'    ;CAT
869   C2D7   27C5             DW      TLIST
870   C2D9   5345             DB      'SE'    ;SET COMMAND
8711
872 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
873+                                                      19:09  05/27/2017
874+                                                                                      PAGE 16
875
876
877
878   C2DB   76C5             DW      CSET
879   C2DD   4355             DB      'CU'    ;CUSTOM COMMAND ENTER/CLEAR
880   C2DF   B9C5             DW      CUSET
881   C2E1   00               DB      0       ;END OF TABLE MARK
882                   ;
883                   ;
884                   ;               DISPLAY DRIVER COMMAND TABLE
885                   ;
886                   ;     THIS TABLE DEFINES THE CHARACTERS FOR SPECIAL
887                   ;  PROCESSING. IF THE CHARACTER IS NOT IN THE TABLE IT
888                   ;  GOES TO THE SCREEN.
889                   ;
890   C2E2   0B       TBL:    DB      CLEAR   ;SCREEN
891   C2E3   F9C0             DW      PERSE
892   C2E5   17               DB      UP      ;CURSOR
893   C2E6   2DC1             DW      PUP
894   C2E8   1A               DB      DOWN    ;"
895   C2E9   EFC0             DW      PDOWN
896   C2EB   01               DB      LEFT    ;"
897   C2EC   34C1             DW      PLEFT
898   C2EE   13               DB      RIGHT   ;"
899   C2EF   3EC1             DW      PRIT
900   C2F1   0E               DB      HOME    ;"
901   C2F2   09C1             DW      PHOME
902   C2F4   0D               DB      CR      ;CARRIAGE RETURN
903   C2F5   70C1             DW      PCR
904   C2F7   0A               DB      LF      ;LINE FEED
905   C2F8   75C1             DW      PLF
906   C2FA   08               DB      BACKS   ;BACK SPACE
907   C2FB   67C1             DW      PBACK
908   C2FD   1B               DB      ESC     ;ESCAPE KEY
909   C2FE   81C1             DW      PESC
910   C300   00               DB      0       ;END OF TABLE
911                   ;
912                   ;   OUTPUT DEVICE TABLE
913                   ;
914   C301   78C0     OTAB:   DW      VDM01   ;VDM DRIVER
915   C303   47C0             DW      SEROT   ;SERIAL OUTPUT
916   C305   5AC0             DW      PAROT   ;PARALLEL OUTPUT
917   C307   6CC0             DW      ERROT   ;ERROR OR USER DRIVER HANDLER
918                   ;
919                   ;    INPUT DEVICE TABLE
920                   ;
921   C309   35C0     ITAB:   DW      KREA1   ;KEYBOARD INPUT
922   C30B   3EC0             DW      SREA1   ;SERIAL INPUT
923   C30D   52C0             DW      PARIT   ;PARALLEL INPUT
924   C30F   65C0             DW      ERRIT   ;ERROR OR USER DRIVER HANDLER
925                   ;
926                   ;
927                   ;       SECONDARY COMMAND TABLE FOR SET COMMAND
928                   ;
9291
930 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
931+                                                      19:09  05/27/2017
932+                                                                                      PAGE 17
933
934
935
936   C311   5441     SETAB:  DB      'TA'    ;SET TAPE SPEED
937   C313   8AC5             DW      TASPD
938   C315   533D             DB      'S='    ;SET DISPLAY SPEED
939   C317   95C5             DW      DISPD
940   C319   493D             DB      'I='    ;SET INPUT PORT
941   C31B   99C5             DW      SETIN
942   C31D   4F3D             DB      'O='    ;SET OUTPUT PORT
943   C31F   9DC5             DW      SETOT
944   C321   4349             DB      'CI'    ;SET CUSTOM DRIVER ADDRESS
945   C323   A1C5             DW      SETCI
946   C325   434F             DB      'CO'    ;SET CUSTOM OUTPUT DRIVER ADDRESS
947   C327   A5C5             DW      SETCO
948   C329   5845             DB      'XE'    ;SET HEADER XEQ ADDRESS
949   C32B   ADC5             DW      SETXQ
950   C32D   5459             DB      'TY'    ;SET HEADER TYPE
951   C32F   A9C5             DW      SETTY
952   C331   4E3D             DB      'N='    ;SET NUMBER OF NULLS
953   C333   B1C5             DW      SETNU
954   C335   4352             DB      'CR'    ;SET CRC (NORMAL OR IGNORE CRC ERRORS)
955   C337   B5C5             DW      SETCR
956   C339   00               DB      0       ;END OF TABLE MARK
957                   ; -*-
958                   ;
959                   ;
960                   ;      OUTPUT A CRLF FOLLOWED BY A PROMPT
961                   ;
962   C33A   CD42C3   PROMPT: CALL    CRLF
963   C33D   063E             MVI     B,'>'   ;THE PROMPT
964   C33F   C319C0           JMP     SOUT    ;PUT IT ON THE SCREEN
965                   ;
966   C342   060A     CRLF:   MVI     B,LF    ;LINE FEED
967   C344   CD19C0           CALL    SOUT
968   C347   060D             MVI     B,CR    ;CARRIAGE RETURN
969   C349   CD19C0           CALL    SOUT
970   C34C   3A10C8           LDA     NUCNT   ;GET COUNT OF NULLS TO OUTPUT
971   C34F   4F               MOV     C,A     ;SAVE COUNT IN C
972   C350   0D       NULOT:  DCR     C
973   C351   F8               RM              ;COUNTED DOWN PAST ZERO (MAX COUNT IS X'7F')
974   C352   AF               XRA     A       ;HERE IS THE NULL
975   C353   CD10C4           CALL    OUTH    ;OUTPUT IT
976   C356   C350C3           JMP     NULOT   ;LOOP FOR NUMBER OF NULLS
977                   ;
978                   ;
979                   ;  SCAN OVER UP TO 12 CHARACTERS LOOKING FOR A BLANK
980                   ;
981   C359   0E0C     SBLK:   MVI     C,12    ;MAXIMUM COMMAND STRING
982   C35B   1A       SBLK1:  LDAX    D
983   C35C   FE20             CPI     BLANK
984   C35E   CA6CC3           JZ      SCHR    ;GOT A BLANK NOW SCAN PAST IT
985   C361   13               INX     D
986   C362   FE3D             CPI     '='     ;A EQUAL WILL ALSO STOP US (AT NEXT CHAR)
9871
988 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
989+                                                      19:09  05/27/2017
990+                                                                                      PAGE 18
991
992
993
994   C364   CA6CC3           JZ      SCHR    ;FOUND, DE PT TO NEXT CHAR
995   C367   0D               DCR     C       ;NO MORE THAN TWELVE
996   C368   C25BC3           JNZ     SBLK1
997   C36B   C9               RET             ;GO BACK WITH ZERO FLAG SET
998                   ;
999                   ;
1000                   ;  SCAN PAST UP TO 10 BLANK POSITIONS LOOKING FOR
1001                   ; A NON BLANK CHARACTER.
1002                   ;
1003   C36C   0E0A     SCHR:   MVI     C,10    ;SCAN TO FIRST NON BLANK CHR WITHIN 10
1004   C36E   1A       SCHR1:  LDAX    D       ;GET NEXT CHARACTER
1005   C36F   FE20             CPI     SPACE
1006   C371   C0               RNZ             ;WE'RE PAST THEM
1007   C372   13               INX     D       ;NEXT SCAN ADDRESS
1008   C373   0D               DCR     C
1009   C374   C8               RZ              ;COMMAND ERROR
1010   C375   C36EC3           JMP     SCHR1   ;KEEP LOOPING
1011                   ;
1012                   ;  THIS ROUTINE SCANS OVER CHARACTERS, PAST BLANKS AND
1013                   ; CONVERTS THE FOLLOWING ADDRESS TO HEX.  ERRORS RETURN TO
1014                   ; THE ERROR HANDLER.
1015                   ;
1016   C378   CD59C3   SCONV:  CALL    SBLK
1017   C37B   CA6BC4           JZ      ERR1
1018                   ;
1019                   ;  THIS ROUTINE CONVERTS ASCII DIGITS INTO BINARY FOLLOWING
1020                   ; A STANDARD HEX CONVERSION.  THE SCAN STOPS WHEN AN ASCII
1021                   ; SPACE IS ENCOUNTERED.  PARAMETER ERRORS REPLACE THE ERROR
1022                   ; CHARACTER ON THE SCREEN WITH A QUESTION MARK.
1023                   ;
1024   C37E   210000   SHEX:   LXI     H,0     ;CLEAR H & L
1025   C381   1A       SHE1:   LDAX    D       ;GET CHARACTER
1026   C382   FE20             CPI     20H     ;IS IT A SPACE?
1027   C384   C8               RZ              ;IF SO
1028   C385   FE2F             CPI     '/'
1029   C387   C8               RZ
1030   C388   FE3A             CPI     ':'
1031   C38A   C8               RZ
1032                   ;
1033   C38B   29       HCONV:  DAD     H       ;MAKE ROOM FOR THE NEW ONE
1034   C38C   29               DAD     H
1035   C38D   29               DAD     H
1036   C38E   29               DAD     H
1037   C38F   CD9BC3           CALL    HCOV1   ;DO THE CONVERSION
1038   C392   D26BC4           JNC     ERR1    ;NOT VALID HEXIDECIMAL VALUE
1039   C395   85               ADD     L
1040   C396   6F               MOV     L,A     ;MOVE IT IN
1041   C397   13               INX     D       ;BUMP THE POINTER
1042   C398   C381C3           JMP     SHE1
1043                   ;
1044   C39B   D630     HCOV1:  SUI     48      ;REMOVE ASCII BIAS
10451
1046 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1047+                                                      19:09  05/27/2017
1048+                                                                                      PAGE 19
1049
1050
1051
1052   C39D   FE0A             CPI     10
1053   C39F   D8               RC              ;IF LESS THAN 9
1054   C3A0   D607             SUI     7       ;IT'S A LETTER??
1055   C3A2   FE10             CPI     10H
1056   C3A4   C9               RET             ;WITH TEST IN HAND
1057                   ;
1058                   ;
1059                   ;  THIS ROUTINE WILL SEE IF A FIELD (OPERAND) IS PRESENT.
1060                   ;  IF NOT, THEN HL WILL REMAIN AS THEY WERE ON ENTRY.
1061                   ;  IF IT WAS PRESENT, THEN HL=THAT VALUE IN HEX.
1062                   ;
1063   C3A5            PSCAN   EQU     $       ;OPTIONAL FIELD SCANNER
1064   C3A5   CD59C3           CALL    SBLK    ;SEE IF FIELD IS PRESENT
1065   C3A8   C8               RZ              ;RETURN LEAVING HL AS THEY WERE ON ENTRY
1066   C3A9   CD7EC3           CALL    SHEX    ;FIELD IS THERE, GO GET IT
1067   C3AC   C9               RET             ;HL= EITHER OPTIONAL FIELD (HEX), OR AS IT WAS
1068                   ;
1069                   ;
1070                   ;
1071                   ;
1072                   ;           DUMP COMMAND
1073                   ;
1074                   ;     THIS ROUTINE DUMPS CHARACTERS FROM MEMORY TO THE
1075                   ;  CURRENT OUTPUT DEVICE.
1076                   ;  ALL VALUES ARE DESPLAYED AS ASCII HEX.
1077                   ;
1078                   ;  THE COMMAND FORM IS AS FOLLOWS:
1079                   ;
1080                   ;        DUMP  ADDR1  ADDR2
1081                   ;
1082                   ;    THE VALUES FROM ADDR1 TO ADDR2 ARE THEN OUTPUT TO THE
1083                   ;  OUTPUT DEVICE.  IF ONLY ADDR1 IS SPECIFIED THEN THE
1084                   ;  VALUE AT THAT ADDRESS IS OUTPUT.
1085                   ;
1086                   ;  IF WHILE DUMPING, THE MODE KEY IS PRESSED, THE DUMP WILL
1087                   ;  BE TERMINATED.  IF THE SPACE BAR IS PRESSED, THE DUMP
1088                   ;  WILL BE TEMPORARILY SUSPENDED UNTIL ANY KEY IS PRESSED.
1089                   ;
1090   C3AD            DUMP    EQU     $       ;SET UP REGS TO DUMP SPECIFIED AREA
1091   C3AD   CD78C3           CALL    SCONV   ;GET START ADDR (REQUIRED)
1092   C3B0   E5               PUSH    H       ;SAVE THE START ADDR
1093   C3B1   CDA5C3           CALL    PSCAN   ;GET OPTIONAL END ADDR, HL=THIS OR START ADDR
1094   C3B4   D1               POP     D       ;DE=START ADDR
1095   C3B5   EB               XCHG            ;DE=END ADDR, HL=START ADDR NOW
1096                   ;
1097   C3B6   CD42C3   DLOOP:  CALL    CRLF
1098   C3B9   CDD9C3           CALL    ADOUT   ;OUTPUT ADDRESS
1099   C3BC   CDF7C3           CALL    BOUT    ;ANOTHER SPACE TO KEEP IT PRETTY
1100   C3BF   0E10             MVI     C,16    ;VALUES PER LINE
1101                   ;
1102   C3C1   7E       DLP1:   MOV     A,M     ;GET THE CHR
11031
1104 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1105+                                                      19:09  05/27/2017
1106+                                                                                      PAGE 20
1107
1108
1109
1110   C3C2   C5               PUSH    B       ;SAVE VALUE COUNT
1111   C3C3   CDDEC3           CALL    HBOUT   ;SEND IT OUT WITH A BLANK
1112   C3C6   7C               MOV     A,H     ;CRNT ADDR
1113   C3C7   BA               CMP     D       ;VERSUS ENDING ADDR
1114   C3C8   DAD0C3           JC      DLP1A   ;NOT DONE YET
1115   C3CB   7D               MOV     A,L     ;TRY LOW ORDER BYTE
1116   C3CC   BB               CMP     E
1117   C3CD   D218C2           JNC     COMND   ;ALL DONE WHEN CRNT REACHES ENDING
1118   C3D0            DLP1A   EQU     $       ;HERE TO KEEP DUMPING
1119   C3D0   C1               POP     B       ;VALUES PER LINE
1120   C3D1   23               INX     H
1121   C3D2   0D               DCR     C       ;BUMP THE LINE COUNT
1122   C3D3   C2C1C3           JNZ     DLP1    ;NOT ZERO IF MORE FOR THIS LINE
1123   C3D6   C3B6C3           JMP     DLOOP   ;DO A LFCR BEFORE THE NEXT
1124                   ;
1125                   ;    OUTPUT HL AS HEX 16 BIT VALUE
1126                   ;
1127   C3D9   7C       ADOUT:  MOV     A,H     ;H FIRST
1128   C3DA   CDFCC3           CALL    HEOUT
1129   C3DD   7D               MOV     A,L     ;THEN L FOLLOWED BY A SPACE
1130                   ;
1131   C3DE   CDFCC3   HBOUT:  CALL    HEOUT
1132   C3E1   CD1FC0           CALL    SINP    ;SEE IF WE SHD ESCAPE FM DUMP
1133   C3E4   CAF7C3           JZ      BOUT    ;NO--ADD THE SPACE THEN
1134   C3E7   E67F             ANI     7FH     ;MAKE SURE ITS CLEAR OF PARITY
1135   C3E9   CA18C2           JZ      COMND   ;EITHER MODE (OR CTL-@)
1136   C3EC   FE20             CPI     ' '     ;IS IT SPACE
1137   C3EE   C2F7C3           JNZ     BOUT    ;NO--IGNORE THE CHAR
1138   C3F1   CD1FC0   WTLP1:  CALL    SINP    ;ON SPACE, WAIT FOR ANY OTHER CHAR
1139   C3F4   CAF1C3           JZ      WTLP1   ;JUST LOOP AFTER A SPACE UNTIL ANY KEY PRESSED
1140   C3F7   0620     BOUT:   MVI     B,' '
1141   C3F9   C319C0           JMP     SOUT    ;PUT IT OUT
1142                   ;
1143   C3FC   4F       HEOUT:  MOV     C,A     ;GET THE CHARACTER
1144   C3FD   0F               RRC
1145   C3FE   0F               RRC             ;MOVE THE HIGH FOUR DOWN
1146   C3FF   0F               RRC
1147   C400   0F               RRC
1148   C401   CD05C4           CALL    HEOU1   ;PUT THEM OUT
1149   C404   79               MOV     A,C     ;THIS TIME THE LOW FOUR
1150                   ;
1151   C405   E60F     HEOU1:  ANI     0FH     ;FOUR ON THE FLOOR
1152   C407   C630             ADI     48      ;WE WORK WITH ASCII HERE
1153   C409   FE3A             CPI     58      ;0-9?
1154   C40B   DA10C4           JC      OUTH    ;YUP!
1155   C40E   C607             ADI     7       ;MAKE IT A LETTER
1156   C410   47       OUTH:   MOV     B,A     ;OUTPUT IT FROM REGISTER 'B'
1157   C411   C319C0           JMP     SOUT
1158                   ;
1159                   ;
1160                   ;           ENTR COMMAND
11611
1162 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1163+                                                      19:09  05/27/2017
1164+                                                                                      PAGE 21
1165
1166
1167
1168                   ;
1169                   ;   THIS ROUTINE GETS VALUES FROM THE KEYBOARD AND ENTERS
1170                   ; THEM INTO MEMORY.  THE INPUT VALUES ARE SCANNED FOLLOWING
1171                   ; A STANDARD 'GCLIN' INPUT SO ON-SCREEN EDITING MAY TAKE
1172                   ; PLACE PRIOR TO THE LINE TERMINATOR.  A SLASH '/'
1173                   ; ENDS THE ROUTINE AND RETURNS CONTROL TO THE COMMAND MODE.
1174                   ;
1175   C414   CD78C3   ENTER:  CALL    SCONV   ;SCAN OVER CHARS AND GET ADDRESS
1176   C417   E5               PUSH    H       ;SAVE ADDRESS
1177                   ;
1178   C418   CD42C3   ENLOP:  CALL    CRLF
1179   C41B   063A             MVI     B,':'
1180   C41D   CD19C0           CALL    SOUT    ;DSPLY THE COLON
1181   C420   CD27C2           CALL    GCLI0   ;INIT AND PROCESS A LINE
1182   C423   CDAAC2           CALL    STUP    ;SET UP TO PROCESS INPUT LINE
1183   C426   EB               XCHG            ;....TO DE
1184                   ;
1185                   ;
1186   C427   0E03     ENLO1:  MVI     C,3     ;NO MORE THAN THREE SPACES BETWEEN VALUES
1187   C429   CD6EC3           CALL    SCHR1   ;SCAN TO NEXT VALUE
1188   C42C   CA18C4           JZ      ENLOP   ;LAST ENTRY FOUND START NEW LINE
1189                   ;
1190   C42F   FE2F             CPI     '/'     ;COMMAND TERMINATOR?
1191   C431   CA18C2           JZ      COMND   ;IF SO...
1192   C434   CD7EC3           CALL    SHEX    ;CONVERT VALUE
1193   C437   FE3A             CPI     ':'     ;ADDRESS TERMINATOR?
1194   C439   CA44C4           JZ      ENLO3   ;GO PROCESS IF SO
1195   C43C   7D               MOV     A,L     ;GET LOW PART AS CONVERTED
1196   C43D   E1               POP     H       ;GET MEMORY ADDRESS
1197   C43E   77               MOV     M,A     ;PUT IN THE VALUE
1198   C43F   23               INX     H
1199   C440   E5               PUSH    H       ;BACK GOES THE ADDRESS
1200   C441   C327C4           JMP     ENLO1   ;CONTINUE THE SCAN
1201                   ;
1202   C444   E3       ENLO3:  XTHL            ;PUT NEW ADDRESS ON STACK
1203   C445   13               INX     D       ;MOVE SCAN PAST TERMINATOR
1204   C446   C327C4           JMP     ENLO1
1205                   ;
1206                   ;
1207                   ;              EXECUTE COMMAND
1208                   ;
1209                   ;   THIS ROUTINE GETS THE FOLLOWING PARAMETER AND DOES A
1210                   ; PROGRAM JUMP TO THE LOCATION GIVEN BY IT.  IF PROPER
1211                   ; STACK OPERATIONS ARE USED WITHIN THE EXTERNAL PROGRAM
1212                   ; IT CAN DO A STANDARD 'RET'URN TO THE CUTER COMMAND MODE.
1213                   ;
1214                   ;
1215   C449   CD78C3   EXEC:   CALL    SCONV   ;SCAN PAST BLANKS AND GET PARAMETER
1216   C44C            EXEC1   EQU     $       ;HERE TO GO TO HL
1217   C44C   E5               PUSH    H       ;SAVE ON STACK
1218   C44D   2100C0           LXI     H,START ;LET USER KNOW WHERE WE ARE
12191
1220 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1221+                                                      19:09  05/27/2017
1222+                                                                                      PAGE 22
1223
1224
1225
1226   C450   C9               RET             ;AND OFF TO USER
1227                   ;
1228                   ;
1229                   ;
1230                   ;
1231                   ;   THIS ROUTINE GETS A NAME OF UP TO 5 CHARACTERS
1232                   ;  FROM THE INPUT STRING.  IF THE TERMINATOR IS A
1233                   ;  SLASH (/) THEN THE CHARACTER FOLLOWING IS TAKEN
1234                   ;  AS THE CASSETTE UNIT SPECIFICATION.
1235                   ;
1236                   ;
1237   C451            NAME0   EQU     $       ;ENTER HERE TO SET HL TO THEAD
1238   C451   211CC8           LXI     H,THEAD ;PT WHERE TO PUT NAME
1239   C454   CD59C3   NAME:   CALL    SBLK    ;SCAN OVER TO FIRST CHRS
1240   C457   0606             MVI     B,6
1241                   ;
1242   C459   1A       NAME1:  LDAX    D       ;GET CHARACTER
1243   C45A   FE20             CPI     ' '     ;NO UNIT DELIMITER
1244   C45C   CA80C4           JZ      NFIL
1245   C45F   FE2F             CPI     '/'     ;UNIT DELIMITER
1246   C461   CA80C4           JZ      NFIL
1247   C464   77               MOV     M,A
1248   C465   13               INX     D       ;BUMP THE SCAN POINTER
1249   C466   23               INX     H
1250   C467   05               DCR     B
1251   C468   C259C4           JNZ     NAME1   ;NAME IS OK, FALL THRU TO 'ERR1' IF NOT
1252                   ;
1253                   ;     CUTER ERROR HANDLER
1254                   ;
1255   C46B   EB       ERR1:   XCHG            ;GET SCAN ADDRESS
1256   C46C   363F     ERR2:   MVI     M,'?'   ;FLAG THE ERROR
1257   C46E   3A07C8           LDA     OPORT   ;SEE IF VIA VDM DRIVER
1258   C471   B7               ORA     A
1259   C472   CA18C2           JZ      COMND   ;YES--VDM SCREEN NOW HAS THE ?
1260   C475   CD42C3           CALL    CRLF
1261   C478   063F             MVI     B,'?'   ;SET UP THE ????
1262   C47A   CD19C0           CALL    SOUT    ;INDICATE INPUT NOT VALID
1263   C47D   C318C2           JMP     COMND   ;NOW READY FOR NEXT INPUT
1264                   ;
1265                   ;
1266                   ;
1267                   ;  HERE WE HAVE SCANNED OFF THE NAME. ZERO FILL IN FOR
1268                   ;  NAMES LESS THAN FIVE CHARACTERS.
1269                   ;
1270   C480   3600     NFIL:   MVI     M,0     ;PUT IN AT LEAST ONE ZERO
1271   C482   23               INX     H
1272   C483   05               DCR     B
1273   C484   C280C4           JNZ     NFIL    ;LOOP UNTIL B IS ZERO
1274                   ;
1275   C487   FE2F             CPI     '/'     ;IS THERE A UNIT SPECIFICATION?
1276   C489   3E01             MVI     A,1     ;PRETEND NOT
12771
1278 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1279+                                                      19:09  05/27/2017
1280+                                                                                      PAGE 23
1281
1282
1283
1284   C48B   C294C4           JNZ     DEFLT
1285   C48E   13               INX     D       ;MOVE PAST THE TERMINATOR
1286   C48F   CD6CC3           CALL    SCHR    ;GO GET IT
1287   C492   D630             SUI     '0'     ;REMOVE ASCII BIAS
1288                   ;
1289   C494            DEFLT   EQU     $       ;CNVRT TO INTERNAL BIT FOR TAPE CONTROL
1290   C494   E601             ANI     1       ;JUST BIT ZERO
1291   C496   3E80             MVI     A,TAPE1 ;ASSUME TAPE ONE
1292   C498   C29CC4           JNZ     STUNT   ;IF NON ZERO, IT IS ONE
1293   C49B   1F               RAR             ;ELSE MAKE IT TAPE TWO
1294   C49C   3254C8   STUNT:  STA     FNUMF   ;SET IT IN
1295   C49F   C9               RET
1296                   ;
1297                   ;
1298                   ;
1299                   ;   THIS ROUTINE PROCESSES THE XEQ AND GET COMMANDS
1300                   ;
1301                   ;
1302   C4A0   3E       TXEQ:   DB      3EH     ;THIS BEGINS "MVI" OF THE "XRA" FOLLOWING
1303   C4A1   AF       TLOAD:  XRA     A       ;A=0 TLOAD, A=AF (#0) THEN XEQ
1304   C4A2   F5               PUSH    PSW     ;SAVE FLAG TO SAY WHETHER LOAD OR XEQ
1305   C4A3   212CC8           LXI     H,DHEAD ;PLACE DUMMY HDR HERE FOR COMPARES
1306   C4A6   CD54C4           CALL    NAME    ;SET IN NAME AND UNIT
1307   C4A9   210000           LXI     H,0     ;ASSUME LOAD ADDR NOT GIVEN
1308   C4AC   CDA5C3           CALL    PSCAN   ;HL EITHER =0, OR OVERRIDE LOAD ADDR
1309                   ;
1310   C4AF   EB       TLOA2:  XCHG            ;PUT ADDRESS IN DE
1311   C4B0   212CC8           LXI     H,DHEAD ;PT TO NORMAL HDR
1312   C4B3   7E               MOV     A,M     ;GET 1ST CHAR OF NAME
1313   C4B4   B7               ORA     A       ;IS THERE A NAME?
1314   C4B5   C2BBC4           JNZ     TLOA3   ;YES--LOOK FOR IT
1315   C4B8   211CC8           LXI     H,THEAD ;PT TO SAME HDR TO LOAD NEXT FILE
1316   C4BB   E5       TLOA3:  PUSH    H       ;SAVE PTR TO WHICH HDR TO USE
1317   C4BC   CD44C5           CALL    ALOAD   ;GET UNIT AND SPEED
1318   C4BF   E1               POP     H       ;RESTORE PTR TO PROPER HDR TO USE
1319   C4C0   CDC7C6           CALL    RTAPE   ;READ IN THE TAPE
1320   C4C3   DA10C5           JC      TAERR   ;TAPE ERROR?
1321                   ;
1322   C4C6   CD4CC5           CALL    NAOUT   ;PUT OUT THE HEADER PARAMETERS
1323   C4C9   F1               POP     PSW     ;RESTORE FLAG SAYING WHETHER IT WAS LOAD OR XEQ
1324   C4CA   B7               ORA     A
1325   C4CB   C8               RZ              ;AUTO XEQ NOT WANTED
1326   C4CC   3A22C8           LDA     HTYPE   ;CHECK TYPE
1327   C4CF   B7               ORA     A       ;SET FLAGS
1328   C4D0   FA10C5           JM      TAERR   ;TYPE IS NON XEQ
1329   C4D3   3A21C8           LDA     THEAD+5
1330   C4D6   B7               ORA     A
1331   C4D7   C210C5           JNZ     TAERR   ;THE BYTE MUST BE ZERO FOR AUTO XEQ
1332   C4DA   2A27C8           LHLD    XEQAD   ;GET THE TAPE ADDRESS
1333   C4DD   C34CC4           JMP     EXEC1   ;AND GO OFF TO IT
1334                   ;
13351
1336 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1337+                                                      19:09  05/27/2017
1338+                                                                                      PAGE 24
1339
1340
1341
1342                   ;
1343                   ;
1344                   ;   THIS ROUTINE IS USED TO SAVE PROGRAMS AND DATA ON
1345                   ;   THE CASSETTE UNIT.
1346                   ;
1347                   ;
1348   C4E0            TSAVE   EQU     $       ;SAVE MEMORY IMAGE TO TAPE
1349   C4E0   CD51C4           CALL    NAME0   ;GET NAME AND UNIT
1350   C4E3   CD78C3           CALL    SCONV   ;GET START ADDRESS
1351   C4E6   E5               PUSH    H       ;SAVE START ADDR FOR SIZE COMPUTATION LATER
1352   C4E7   CD78C3           CALL    SCONV   ;GET END ADDR (REQUIRED)
1353   C4EA   E3               XTHL            ;HL=START ADDR NOW, STACK=END ADDR
1354   C4EB   E5               PUSH    H       ;STACK =START FOLLOWED BY END
1355   C4EC   CDA5C3           CALL    PSCAN   ;SEE IF RETRIEVE FROM ADDR
1356   C4EF   2225C8           SHLD    LOADR   ;EITHER ACTUAL START, OR OVERRIDE INTO HDR
1357   C4F2   E1               POP     H       ;HL=START ADDR
1358   C4F3   D1               POP     D       ;DE=END ADDR
1359   C4F4   E5               PUSH    H       ;PUT START BACK ONTO STACK
1360   C4F5   7B               MOV     A,E     ;SIZE=END-START+1
1361   C4F6   95               SUB     L
1362   C4F7   6F               MOV     L,A
1363   C4F8   7A               MOV     A,D
1364   C4F9   DE00             SBI     0       ;THIS EQUALS A "SBB H"
1365   C4FB   94               SUB     H       ;THIS IS NEEDED
1366   C4FC   67               MOV     H,A
1367   C4FD   23               INX     H
1368   C4FE   2223C8           SHLD    BLOCK   ;STORE THE SIZE
1369   C501   E5               PUSH    H       ;SAVE AS THE BLOCK SIZE
1370                   ;
1371   C502   CD44C5           CALL    ALOAD   ;GET UNIT AND SPEED
1372   C505   211CC8           LXI     H,THEAD ;PT TO HEADER TO WRITE
1373   C508   CDADC7           CALL    WHEAD   ;TURN TAPE ON, THEN WRITE HEADER
1374   C50B   D1               POP     D       ;GET BACK THE SIZE
1375   C50C   E1               POP     H       ;AND GET BACK THE ACTUAL START ADDR
1376   C50D   C38DC7           JMP     WTAP1   ;WRITE THE BLK (W/EXTRA PUSH)
1377                   ;
1378                   ;   OUTPUT ERROR AND HEADER
1379                   ;
1380   C510   CD42C3   TAERR:  CALL    CRLF
1381   C513   1606             MVI     D,6
1382   C515   2121C5           LXI     H,ERRM
1383   C518   CD66C5           CALL    NLOOP   ;OUTPUT ERROR
1384   C51B   CD4CC5           CALL    NAOUT   ;THEN THE HEADER
1385   C51E   C315C2           JMP     COMN1
1386                   ;
1387   C521   4552524F ERRM:   DB      'ERROR '
1388   C525   5220
1389
1390                   ;
1391                   ;
1392                   ;              CAT COMMAND
13931
1394 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1395+                                                      19:09  05/27/2017
1396+                                                                                      PAGE 25
1397
1398
1399
1400                   ;
1401                   ;   THIS ROUTINE READS HEADERS FROM THE TAPE AND OUTPUTS
1402                   ;   THEM TO THE OUTPUT DEVICE.  IT CONTINUES UNTIL THE
1403                   ;   MODE KEY IS DEPRESSED.
1404                   ;
1405   C527            TLIST   EQU     $       ;PRODUCE A LIST OF FILES ON A TAPE
1406   C527   CD51C4           CALL    NAME0   ;GET UNIT IF ANY (NAME IS IGNORED)
1407   C52A   CD42C3           CALL    CRLF    ;START ON A FRESH LINE
1408                   ;
1409                   ;
1410   C52D   CD44C5   LLIST:  CALL    ALOAD
1411   C530   0601             MVI     B,1
1412   C532   CDEDC7           CALL    TON     ;TURN ON THE TAPE
1413   C535   CD1FC7   LIST1:  CALL    RHEAD
1414   C538   DA15C2           JC      COMN1   ;TRUN OFF THE TAPE UNIT
1415   C53B   C235C5           JNZ     LIST1
1416   C53E   CD4CC5           CALL    NAOUT   ;OUTPUT THE HEADER
1417   C541   C32DC5           JMP     LLIST
1418                   ;
1419                   ;
1420                   ;   THIS ROUTINE GETS THE CASSETTE UNIT NUMBER AND
1421                   ;   SPEED TO REGISTER "A" FOR THE TAPE CALLS
1422                   ;
1423   C544   2154C8   ALOAD:  LXI     H,FNUMF ;POINT TO THE UNIT SPECIFICATION
1424   C547   3A0DC8           LDA     TSPD    ;GET THE TAPE SPEED
1425   C54A   B6               ORA     M       ;PUT THEM TOGETHER
1426   C54B   C9               RET             ;AND GO BACK
1427                   ;
1428                   ;   THIS ROUTINE OUTPUTS THE NAME AND PARAMETERS OF
1429                   ;   THEAD TO THE OUTPUT DEVICE.
1430                   ;
1431                   ;
1432   C54C   1608     NAOUT:  MVI     D,8
1433   C54E   211BC8           LXI     H,THEAD-1 ;POINT TO THE HEADER
1434   C551   CD66C5           CALL    NLOOP   ;OUTPUT THE HEADER
1435   C554   CDF7C3           CALL    BOUT    ;ANOTHER BLANK
1436   C557   2A25C8           LHLD    LOADR   ;NOW THE LOAD ADDRESS
1437   C55A   CDD9C3           CALL    ADOUT   ;PUT IT OUT
1438   C55D   2A23C8           LHLD    BLOCK   ;AND THE BLOCK SIZE
1439   C560   CDD9C3           CALL    ADOUT
1440   C563   C342C3           JMP     CRLF    ;DO THE CRLF AND RETURN
1441                   ;
1442                   ;
1443   C566   7E       NLOOP:  MOV     A,M     ;GET CHARACTER
1444   C567   B7               ORA     A
1445   C568   C26DC5           JNZ     CHRLI   ;IF IT ISN'T A ZERO
1446   C56B   3E20             MVI     A,' '   ;SPACE OTHERWISE
1447   C56D            CHRLI   EQU     $       ;CHAR IS OK TO SEND
1448   C56D   CD10C4           CALL    OUTH    ;OUTPUT IT FROM A REG
1449   C570   23               INX     H
1450   C571   15               DCR     D
14511
1452 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1453+                                                      19:09  05/27/2017
1454+                                                                                      PAGE 26
1455
1456
1457
1458   C572   C266C5           JNZ     NLOOP
1459   C575   C9               RET
1460                   ;
1461                   ;
1462                   ;
1463                   ;
1464                   ;      "SET" COMMAND
1465                   ;
1466                   ;   THIS ROUTINE GETS THE ASSOCIATED PARAMETER AND
1467                   ;   DISPATCHES TO THE PROPER ROUTINE FOR SETTING
1468                   ;   MEMORY VALUES.
1469                   ;
1470   C576   CD59C3   CSET:   CALL    SBLK    ;SCAN TO SECONDARY COMMAND
1471   C579   CA6BC4           JZ      ERR1    ;MUST HAVE AT LEAST SOMETHING!!
1472   C57C   D5               PUSH    D       ;SAVE SCAN ADDRESS
1473   C57D   CD78C3           CALL    SCONV   ;CONVERT FOLLOWING VALUE
1474   C580   E3               XTHL            ;HL=SAVED SCAN ADDR AND STACK=VALUE
1475   C581   1111C3           LXI     D,SETAB ;SECONDARY COMMAND TABLE
1476   C584   CD91C2           CALL    FDCOM   ;TRY TO LOCATE IT
1477   C587   C382C2           JMP     DISP0   ;OFF TO IT OR ERROR IF NOT IN TBL
1478                   ;
1479                   ;
1480                   ;  THIS ROUTINE SETS THE TAPE SPEED
1481                   ;
1482   C58A            TASPD   EQU     $       ;GET CONVERTED VALUE
1483   C58A   B7               ORA     A       ;IS IT ZERO?
1484   C58B   CA90C5           JZ      SETSP   ;YES--THAT IS A PROPER SPEED
1485   C58E   3E20             MVI     A,32    ;NO--SET SPEED PROPERLY THEN
1486   C590   320DC8   SETSP:  STA     TSPD
1487   C593   C9               RET
1488                   ;
1489                   ;
1490   C594            STSPD   EQU     $       ;VDM ESCAPE SEQUENCE COMES HERE
1491   C594   78               MOV     A,B     ;GET CHAR FOR FOLLOWING DISPD
1492   C595            DISPD   EQU     $       ;SET DISPLAY SPEED
1493   C595   320BC8           STA     SPEED
1494   C598   C9               RET
1495                   ;
1496                   ;
1497   C599            SETIN   EQU     $       ;SET AN INPUT PSUEDO PORT
1498   C599   3206C8           STA     IPORT
1499   C59C   C9               RET
1500                   ;
1501                   ;
1502   C59D            SETOT   EQU     $       ;SET AN OUTPUT PSUEDO PORT
1503   C59D   3207C8           STA     OPORT
1504   C5A0   C9               RET
1505                   ;
1506                   ;
1507   C5A1            SETCI   EQU     $       ;DEFINE USER INPUT RTN ADDR
1508   C5A1   2200C8           SHLD    UIPRT
15091
1510 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1511+                                                      19:09  05/27/2017
1512+                                                                                      PAGE 27
1513
1514
1515
1516   C5A4   C9               RET
1517                   ;
1518                   ;
1519   C5A5            SETCO   EQU     $       ;DEFINE USER OUTPUT RTN ADDR
1520   C5A5   2202C8           SHLD    UOPRT
1521   C5A8   C9               RET
1522                   ;
1523                   ;
1524   C5A9            SETTY   EQU     $       ;SET TAPE HDR TYPE
1525   C5A9   3222C8           STA     HTYPE
1526   C5AC   C9               RET
1527                   ;
1528                   ;
1529   C5AD            SETXQ   EQU     $       ;SET TAPE-EXECUTE ADDDR FOR HDR
1530   C5AD   2227C8           SHLD    XEQAD
1531   C5B0   C9               RET
1532                   ;
1533                   ;
1534   C5B1            SETNU   EQU     $       ;HERE TO SET NUMBER OF NULLS
1535   C5B1   3210C8           STA     NUCNT   ;THIS IS IT
1536   C5B4   C9               RET
1537                   ;
1538                   ;
1539   C5B5            SETCR   EQU     $       ;SET CRC TO BE NORMAL, OR IGNORE CRC ERRORS
1540   C5B5   3211C8           STA     IGNCR   ;FF=IGNORE CRC ERRORS, ELSE=NORMAL
1541   C5B8   C9               RET
1542                   ;
1543                   ;
1544   C5B9            CUSET   EQU     $       ;TRY TO SET/CLEAR CUSTOM ROUTINE ADDR
1545   C5B9   CD51C4           CALL    NAME0   ;GET A NAME (S/B 2 CHARS OR MORE)
1546   C5BC   2118C2           LXI     H,COMND ;PT HERE IN CASE ADDR NOT GIVEN
1547   C5BF   CDA5C3           CALL    PSCAN   ;GET OPTIONAL OPERAND IF ANY
1548   C5C2   E5               PUSH    H       ;SAVE THAT VALUE (IF ANY)
1549   C5C3   211CC8           LXI     H,THEAD ;PT TO NAME
1550   C5C6   CD8EC2           CALL    FDCOU   ;SEE IF NAME IS KNOWN IN CUST TABLE
1551   C5C9   CACFC5           JZ      CUSE2   ;NO--PROCEED TO KNOW IT
1552   C5CC   1B               DCX     D       ;DE PT TO 1ST CHAR OF NAME IN TBL
1553   C5CD   3600             MVI     M,0     ;(HL CAME BACK PT'ING TO THEAD)  CLR THIS NAME
1554   C5CF            CUSE2   EQU     $       ;ENTER NEW ONE IN TBL
1555   C5CF   7E               MOV     A,M     ;GET 1ST CHAR OF NAME
1556   C5D0   12               STAX    D       ;PUT NAME INTO TABLE
1557   C5D1   13               INX     D
1558   C5D2   23               INX     H
1559   C5D3   7E               MOV     A,M     ;GET 2ND CHAR OF NAME
1560   C5D4   12               STAX    D       ;NAME IS NOW POSTED
1561   C5D5   13               INX     D       ;PT TO 1ST BYTE OF ADDR
1562   C5D6   E1               POP     H       ;RESTORE SAVED RTN ADDR
1563   C5D7   EB               XCHG            ;DE=RTN ADDR, HL=THIS CU ENTRY
1564   C5D8   73               MOV     M,E     ;LO BYTE
1565   C5D9   23               INX     H
1566   C5DA   72               MOV     M,D     ;AND HI BYTE
15671
1568 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1569+                                                      19:09  05/27/2017
1570+                                                                                      PAGE 28
1571
1572
1573
1574   C5DB   C9               RET             ;ALL DONE
1575                   ;
1576                   ;
1577                   ; -*-
1578                   ;
1579                   ;
1580                   ;
1581                   ;
1582                   ;   THE FOLLOWING ROUTINES PROVIDE "BYTE BY BYTE" ACCESS
1583                   ;  TO THE CASSETTE TAPES ON EITHER A READ OR WRITE BASIS.
1584                   ;
1585                   ;  THE TAPE IS READ ONE BLOCK AT A TIME AND INDIVIDUAL
1586                   ;  TRANSFERS OF DATA HANDLED BY MANAGING A BUFFER AREA.
1587                   ;
1588                   ;  THE BUFFER AREA IS CONTROLLED BY A FILE CONTROL BLOCK
1589                   ;  (FCB) WHOSE STRUCTURE IS:
1590                   ;
1591                   ;
1592                   ;     7 BYTES FOR EACH OF THE TWO FILES STRUCTURED AS
1593                   ;   FOLLOWS:
1594                   ;
1595                   ;         1 BYTE -  ACCESS CONTROL   00 IF CLOSED
1596                   ;                                    FF IF READING
1597                   ;                                    FE IF WRITING
1598                   ;         1 BYTE -  READ COUNTER
1599                   ;         1 BYTE -  BUFFER POSITION POINTER
1600                   ;         2 BYTE -  CONTROL HEADER ADDRESS
1601                   ;         2 BYTE -  BUFFER LOCATION ADDRESS
1602                   ;
1603                   ;
1604                   ;
1605                   ;        THIS ROUTINE "OPENS" THE CASSETTE UNIT FOR ACCESS
1606                   ;
1607                   ;   ON ENTRY:  A - HAS THE TAPE UNIT NUMBER (1 OR 2)
1608                   ;             HL - HAS USER SUPPLIED HEADER FOR TAPE FILE
1609                   ;
1610                   ;
1611                   ;   NORMAL RETURN:   ALL REGISTERS ARE ALTERED
1612                   ;                    BLOCK IS READY FOR ACCESS
1613                   ;
1614                   ;   ERROR RETURN:    CARRY BIT IS SET
1615                   ;
1616                   ;   ERRORS:  BLOCK ALREADY OPEN
1617                   ;
1618                   ;
1619   C5DC   E5       BOPEN:  PUSH    H       ;SAVE HEADER ADDRESS
1620   C5DD   CD2FC6           CALL    LFCB    ;GET ADDRESS OF FILE CONTROL
1621   C5E0   C2F6C5           JNZ     TERE2   ;FILE WAS ALREADY OPEN
1622   C5E3   3601             MVI     M,1     ;NOW IT IS
1623   C5E5   23               INX     H       ;POINT TO READ COUNT
1624   C5E6   77               MOV     M,A     ;ZERO
16251
1626 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1627+                                                      19:09  05/27/2017
1628+                                                                                      PAGE 29
1629
1630
1631
1632   C5E7   23               INX     H       ;POINT TO BUFFER CURSOR
1633   C5E8   77               MOV     M,A     ;PUT IN THE ZERO COUNT
1634                   ;
1635                   ;  ALLOCATE THE BUFFER
1636                   ;
1637   C5E9   1163C8           LXI     D,FBUF1 ;POINT TO BUFFER AREA
1638   C5EC   3A54C8           LDA     FNUMF   ;GET WHICH ONE WE ARE GOING TO USE
1639   C5EF   82               ADD     D
1640   C5F0   57               MOV     D,A     ;256 BIT ADD
1641                   ;
1642   C5F1   C1       UBUF:   POP     B       ;HEADER ADDRESS
1643   C5F2   B7               ORA     A       ;CLEAR CARRY AND RETURN AFTER STORING PARAMS
1644   C5F3   C3B2C6           JMP     PSTOR   ;STORE THE VALUES
1645                   ;
1646                   ;    GENERAL ERROR RETURN POINTS FOR STACK CONTROL
1647                   ;
1648   C5F6   E1       TERE2:  POP     H
1649   C5F7   D1       TERE1:  POP     D
1650   C5F8   AF       TERE0:  XRA     A       ;CLEAR ALL FLAGS
1651   C5F9   37               STC             ;SET ERROR
1652   C5FA   C9               RET
1653                   ;
1654                   ;
1655   C5FB   3D       EOFER:  DCR     A       ;SET MINUS FLAGS
1656   C5FC   37               STC             ;AND CARRY
1657   C5FD   D1               POP     D       ;CLEAR THE STACK
1658   C5FE   C9               RET             ;THE FLAGS TELL ALL
1659                   ;
1660                   ;
1661                   ;
1662                   ;
1663                   ;   THIS ROUTINE CLOSES THE FILE BUFFER TO ALLOW ACCESS
1664                   ;   FOR A DIFFERENT CASSETTE OR PROGRAM.  IF THE FILE
1665                   ;   OPERATIONS WERE "WRITE" THEN THE LAST BLOCK IS WRITTED
1666                   ;   OUT AND AN "END OF FILE" WRITTEN TO THE TAPE.  IF
1667                   ;   THE OPERATIONS WERE "READS" THEN THE FILE IS JUST
1668                   ;   MADE READY FOR NEW USE.
1669                   ;
1670                   ;   ON ENTRY:  A - HAS WHICH UNIT (1 OR 2)
1671                   ;
1672                   ;   ERROR RETURNS:  FILE WASN'T OPEN
1673                   ;
1674                   ;
1675   C5FF   CD2FC6   PCLOS:  CALL    LFCB    ;GET CONTROL BLOCK ADDRESS
1676   C602   C8               RZ              ;WASN'T OPEN, CARRY IS SET FROM LFCB
1677   C603   B7               ORA     A       ;CLEAR CARRY
1678   C604   3C               INR     A       ;SET CONDITION FLAGS
1679   C605   3600             MVI     M,0     ;CLOSE THE CONTROL BYTE
1680   C607   C8               RZ              ;WE WERE READING...NOTHING MORE TO DO
1681                   ;
1682                   ;    THE FILE OPERATIONS WERE "WRITES"
16831
1684 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1685+                                                      19:09  05/27/2017
1686+                                                                                      PAGE 30
1687
1688
1689
1690                   ;
1691                   ;  PUT THE CURRENT BLOCK ON THE TAPE
1692                   ;  (EVEN IF ONLY ONE BYTE)
1693                   ;  THEN WRITE AN END OF FILE TO THE TAPE
1694                   ;
1695                   ;
1696   C608   23               INX     H
1697   C609   23               INX     H
1698   C60A   7E               MOV     A,M     ;GET CURSOR POSITION
1699   C60B   7E               MOV     A,M     ;GET CURSOR POSITION
1700   C60C   CDBBC6           CALL    PLOAD   ;BC GET HEADER ADDRESS, DE BUFFER ADDRESS
1701   C60F   C5               PUSH    B       ;HEADER TO STACK
1702   C610   210700           LXI     H,BLKOF ;OFFSET TO BLOCK SIZE
1703   C613   09               DAD     B
1704   C614   B7               ORA     A       ;TEST COUNT
1705   C615   CA27C6           JZ      EOFW    ;NO BYTES...JUST WRITE EOF
1706                   ;
1707                   ;    WRITE LAST BLOCK
1708                   ;
1709   C618   E5               PUSH    H       ;SAVE BLOCK SIZE POINTER FOR EOF
1710   C619   77               MOV     M,A     ;PUT IN COUNT
1711   C61A   23               INX     H
1712   C61B   3600             MVI     M,0     ;ZERO THE HIGHER BYTE
1713   C61D   23               INX     H
1714   C61E   73               MOV     M,E     ;BUFFER ADDRESS
1715   C61F   23               INX     H
1716   C620   72               MOV     M,D
1717   C621   60               MOV     H,B
1718   C622   69               MOV     L,C     ;PUT HEADER ADDRESS IN HL
1719   C623   CD79C7           CALL    WFBLK   ;GO WRITE IT OUT
1720   C626   E1               POP     H       ;BLOCK SIZE POINTER
1721                   ;
1722                   ;   NOW WRITE END OF FILE TO CASSETTE
1723                   ;
1724   C627   AF       EOFW:   XRA     A       ;PUT IN ZEROS FOR SIZE:  EOF MARK IS ZERO BYTES!
1725   C628   77               MOV     M,A
1726   C629   23               INX     H
1727   C62A   77               MOV     M,A
1728   C62B   E1               POP     H       ;HEADER ADDRESS
1729   C62C   C379C7           JMP     WFBLK   ;WRITE IT OUT AND RETURN
1730                   ;
1731                   ;
1732                   ;
1733                   ;
1734                   ;   THIS ROUTINE LOCATES THE FILE CONTROL BLOCK POINTED TO
1735                   ;   BY REGISTER "A".  ON RETURN HL POINT TO THE CONTROL BYT
1736                   ;   AND REGISTER "A" HAS THE CONTROL WORD WITH THE FLAGS
1737                   ;   SET FOR IMMEDIATE CONDITION DECISIONS.
1738                   ;
1739                   ;
1740   C62F   2155C8   LFCB:   LXI     H,FCBAS ;POINT TO THE BASE OF IT
17411
1742 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1743+                                                      19:09  05/27/2017
1744+                                                                                      PAGE 31
1745
1746
1747
1748   C632   1F               RAR             ;MOVE THE 1 & 2 TO 0 & 1 LIKE COMPUTERS LIKE
1749   C633   E601             ANI     1       ;SMALL NUMBERS ARE THE RULE
1750   C635   3254C8           STA     FNUMF   ;CURRENT ACCESS FILE NUMBER
1751   C638   CA3EC6           JZ      LFCB1   ;UNIT ONE (VALUE OF ZERO)
1752   C63B   215CC8           LXI     H,FCBA2 ;UNIT TWO--PT TO ITS FCB
1753   C63E            LFCB1   EQU     $       ;HL PT TO PROPER FCB
1754   C63E   7E               MOV     A,M     ;PICK UP FLAGS FM FCB
1755   C63F   B7               ORA     A       ;SET FLAGS BASED ON CONTROL WORD
1756   C640   37               STC             ;SET CARRY IN CASE OF IMMEDIATE ERROR RETURN
1757   C641   C9               RET
1758                   ;
1759                   ;
1760                   ;
1761                   ;
1762                   ;    READ TAPE BYTE ROUTINE
1763                   ;
1764                   ;    ENTRY:       -  A -  HAS FILE NUMBER
1765                   ;    EXIT: NORMAL -  A -  HAS BYTE
1766                   ;          ERROR
1767                   ;            CARRY SET     - IF FILE NOT OPEN OR
1768                   ;                            PREVIOUS OPERATIONS WERE WRITE
1769                   ;            CARRY & MINUS - END OF FILE ENCOUNTERED
1770                   ;
1771                   ;
1772                   ;
1773                   ;
1774   C642   CD2FC6   RTBYT:  CALL    LFCB    ;LOCATE THE FILE CONTROL BLOCK
1775   C645   C8               RZ              ;FILE NOT OPEN
1776   C646   3C               INR     A       ;TEST IF FF
1777   C647   FAF8C5           JM      TERE0   ;ERROR WAS WRITING
1778   C64A   36FF             MVI     M,(-1) AND 0FFH ;SET IT AS READ  (IN CASE IT WAS JUST OPENED)
1779   C64C   23               INX     H
1780   C64D   7E               MOV     A,M     ;GET READ COUNT
1781   C64E   E5               PUSH    H       ;SAVE COUNT ADDRESS
1782   C64F   23               INX     H
1783   C650   CDBBC6           CALL    PLOAD   ;GET THE OTHER PARAMETERS
1784   C653   E1               POP     H
1785   C654   B7               ORA     A
1786   C655   C271C6           JNZ     GTBYT   ;IF NOT EMPTY GO GET BYTE
1787                   ;
1788                   ;  CURSOR POSITION WAS ZERO...READ A NEW BLOCK INTO
1789                   ;  THE BUFFER.
1790                   ;
1791   C658   D5       RDNBLK: PUSH    D       ;BUFFER POINTER
1792   C659   E5               PUSH    H       ;TABLE ADDRESS
1793   C65A   23               INX     H
1794   C65B   CDA2C6           CALL    PHEAD   ;PREPARE THE HEADER FOR READ
1795   C65E   CDC4C6           CALL    RFBLK   ;READ IN THE BLOCK
1796   C661   DAF6C5           JC      TERE2   ;ERROR POP OFF STACK BEFORE RETURN
1797   C664   E1               POP     H
1798   C665   7B               MOV     A,E     ;LOW BYTE OF COUNT (WILL BE ZERO IF 256)
17991
1800 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1801+                                                      19:09  05/27/2017
1802+                                                                                      PAGE 32
1803
1804
1805
1806   C666   B2               ORA     D       ;SEE IF BOTH ARE ZERO
1807   C667   CAFBC5           JZ      EOFER   ;BYTE COUNT WAS ZERO....END OF FILE
1808   C66A   73               MOV     M,E     ;NEW COUNT ( ZERO IS 256 AT THIS POINT)
1809   C66B   23               INX     H       ;BUFFER LOCATION POINTER
1810   C66C   3600             MVI     M,0
1811   C66E   2B               DCX     H
1812   C66F   7B               MOV     A,E     ;COUNT TO A
1813   C670   D1               POP     D       ;GET BACK BUFFER ADDRESS
1814                   ;
1815                   ;
1816                   ;
1817                   ;   THIS ROUTINE GETS ONE BYTE FROM THE BUFFER
1818                   ;  AND RETURNS IT IN REGISTER "A".  IF THE END
1819                   ;  OF THE BUFFER IS REACHED IT MOVES THE POINTER
1820                   ;  TO THE BEGINNING OF THE BUFFER FOR THE NEXT
1821                   ;  LOAD.
1822                   ;
1823   C671   3D       GTBYT:  DCR     A       ;BUMP THE COUNT
1824   C672   77               MOV     M,A     ;RESTORE IT
1825   C673   23               INX     H
1826   C674   7E               MOV     A,M     ;GET BUFFER POSITION
1827   C675   34               INR     M       ;BUMP IT
1828                   ;
1829   C676   83               ADD     E
1830   C677   5F               MOV     E,A     ;DE NOW POINT TO CORRECT BUFFER POSITION
1831   C678   D27CC6           JNC     RT1
1832   C67B   14               INR     D
1833   C67C   1A       RT1:    LDAX    D       ;GET CHARACTER FROM BUFFER
1834   C67D   B7               ORA     A       ;CLEAR CARRY
1835   C67E   C9               RET             ;ALL DONE
1836                   ;
1837                   ;
1838                   ;
1839                   ;
1840                   ;      THIS ROUTINE IS USED TO WRITE A BYTE TO THE FILE
1841                   ;
1842                   ;      ON ENTRY:   A -  HAS FILE NUMBER
1843                   ;                  B -  HAS DATA BYTE
1844                   ;
1845                   ;
1846   C67F   CD2FC6   WTBYT:  CALL    LFCB    ;GET CONTROL BLOCK
1847   C682   C8               RZ              ;FILE WASN'T OPEN
1848   C683   3C               INR     A
1849   C684   C8               RZ              ;FILE WAS READ
1850   C685   36FE             MVI     M,0FEH  ;SET IT TO WRITE
1851   C687   23               INX     H
1852   C688   23               INX     H
1853   C689   78               MOV     A,B     ;GET CHARACTER
1854   C68A   F5               PUSH    PSW
1855   C68B   E5               PUSH    H       ;SAVE CONTROL ADDRESS+2
1856                   ;
18571
1858 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1859+                                                      19:09  05/27/2017
1860+                                                                                      PAGE 33
1861
1862
1863
1864                   ;   NOW DO THE WRITE
1865                   ;
1866   C68C   CDBBC6           CALL    PLOAD   ;BC GETS HEADER ADDR, DE BUFFER ADDRESS
1867   C68F   E1               POP     H
1868   C690   7E               MOV     A,M     ;COUNT BYTE
1869   C691   83               ADD     E
1870   C692   5F               MOV     E,A
1871   C693   D297C6           JNC     WT1
1872   C696   14               INR     D
1873   C697   F1       WT1:    POP     PSW     ;CHARACTER
1874   C698   12               STAX    D       ;PUT CHR IN BUFFER
1875   C699   B7               ORA     A       ;CLEAR FLAGS
1876   C69A   34               INR     M       ;INCREMENT THE COUNT
1877   C69B   C0               RNZ             ;RETURN IF COUNT DIDN'T ROLL OVER
1878                   ;
1879                   ;   THE BUFFER IS FULL. WRITE IT TO TAPE AND RESET
1880                   ;  CONTROL BLOCK.
1881                   ;
1882   C69C   CDA2C6           CALL    PHEAD   ;PREPARE THE HEADER
1883   C69F   C379C7           JMP     WFBLK   ;WRITE IT OUT AND RETURN
1884                   ;
1885                   ;
1886                   ;
1887                   ;
1888                   ;  THIS ROUTINE PUTS THE BLOCK SIZE (256) AND BUFFER
1889                   ;  ADDRESS IN THE FILE HEADER.
1890                   ;
1891   C6A2   CDBBC6   PHEAD:  CALL    PLOAD   ;GET HEADER AND BUFFER ADDRESSES
1892   C6A5   C5               PUSH    B       ;HEADER ADDRESS
1893   C6A6   210600           LXI     H,BLKOF-1 ;PSTOR DOES AN INCREMENT
1894   C6A9   09               DAD     B       ;HL POINT TO BLOCKSIZE ENTRY
1895   C6AA   010001           LXI     B,256
1896   C6AD   CDB2C6           CALL    PSTOR
1897   C6B0   E1               POP     H       ;HL RETURN WITH HEADER ADDRESS
1898   C6B1   C9               RET
1899                   ;
1900                   ;
1901   C6B2   23       PSTOR:  INX     H
1902   C6B3   71               MOV     M,C
1903   C6B4   23               INX     H
1904   C6B5   70               MOV     M,B
1905   C6B6   23               INX     H
1906   C6B7   73               MOV     M,E
1907   C6B8   23               INX     H
1908   C6B9   72               MOV     M,D
1909   C6BA   C9               RET
1910                   ;
1911                   ;
1912   C6BB   23       PLOAD:  INX     H
1913   C6BC   4E               MOV     C,M
1914   C6BD   23               INX     H
19151
1916 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1917+                                                      19:09  05/27/2017
1918+                                                                                      PAGE 34
1919
1920
1921
1922   C6BE   46               MOV     B,M
1923   C6BF   23               INX     H
1924   C6C0   5E               MOV     E,M
1925   C6C1   23               INX     H
1926   C6C2   56               MOV     D,M
1927   C6C3   C9               RET
1928                   ;
1929                   ;
1930                   ;
1931                   ;
1932                   ;
1933                   ;   THIS ROUTINE SETS THE CORRECT UNIT FOR SYSTEM READS
1934   C6C4   CDDCC7   RFBLK:  CALL    GTUNT   ;SET UP A=UNIT WITH SPEED
1935                   ;
1936                   ;
1937                   ;
1938                   ;
1939                   ;              TAPE READ ROUTINES
1940                   ;
1941                   ;     ON-ENTRY:     A HAS UNIT AND SPEED
1942                   ;                   HL POINT TO HEADER BLOCK
1943                   ;                   DE HAVE OPTIONAL PUT ADDRESS
1944                   ;
1945                   ;     ON EXIT:      CARRY IS SET IF ERROR OCCURED
1946                   ;                   TAPE UNITS ARE OFF
1947                   ;
1948                   ;
1949   C6C7   D5       RTAPE:  PUSH    D       ;SAVE OPTIONAL ADDRESS
1950   C6C8   0603             MVI     B,3     ;SHORT DELAY
1951   C6CA   CDEDC7           CALL    TON
1952   C6CD   DB07             IN      TDATA   ;CLEAR THE UART FLAGS
1953                   ;
1954   C6CF   E5       PTAP1:  PUSH    H       ;HEADER ADDRESS
1955   C6D0   CD1FC7           CALL    RHEAD   ;GO READ HEADER
1956   C6D3   E1               POP     H
1957   C6D4   DA02C7           JC      TERR    ;IF AN ERROR OR ESC WAS RECEIVED
1958   C6D7   C2CFC6           JNZ     PTAP1   ;IF VALID HEADER NOT FOUND
1959                   ;
1960                   ;  FOUND A VALID HEADER NOW DO COMPARE
1961                   ;
1962   C6DA   E5               PUSH    H       ;GET BACK AND RESAVE ADDRESS
1963   C6DB   111CC8           LXI     D,THEAD
1964   C6DE   CDD0C7           CALL    DHCMP   ;COMPARE DE-HL HEADERS
1965   C6E1   E1               POP     H
1966   C6E2   C2CFC6           JNZ     PTAP1
1967                   ;
1968                   ;
1969   C6E5   D1               POP     D       ;OPTIONAL "PUT" ADDRESS
1970   C6E6   7A               MOV     A,D
1971   C6E7   B3               ORA     E       ;SEE IF DE IS ZERO
1972   C6E8   2A23C8           LHLD    BLOCK   ;GET BLOCK SIZE
19731
1974 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
1975+                                                      19:09  05/27/2017
1976+                                                                                      PAGE 35
1977
1978
1979
1980   C6EB   EB               XCHG            ;...TO DE
1981                   ;  DE HAS HBLOCK....HL HAS USER OPTION
1982   C6EC   C2F2C6           JNZ     RTAP    ;IF DE WAS ZERO GET TAPE LOAD ADDRESS
1983   C6EF   2A25C8           LHLD    LOADR   ;GET TAPE LOAD ADDRESS
1984                   ;
1985                   ;
1986                   ;     THIS ROUTINE READS "DE" BYTES FROM THE TAPE
1987                   ;     TO ADDRESS HL.  THE BYTES MUST BE FROM ONE
1988                   ;     CONTIGUOUS PHYSICAL BLOCK ON THE TAPE.
1989                   ;
1990                   ;          HL HAS "PUT" ADDRESS
1991                   ;          DE HAS SIZE OF TAPE BLOCK
1992                   ;
1993   C6F2   D5       RTAP:   PUSH    D       ;SAVE SIZE FOR RETURN TO CALLING PROGRAM
1994                   ;
1995   C6F3            RTAP2   EQU     $       ;HERE TO LOOP RDING BLKS
1996   C6F3   CD11C7           CALL    DCRCT   ;DROP COUNT, B=LEN THIS BLK
1997   C6F6   CA0CC7           JZ      RTOFF   ;ZERO=ALL DONE
1998                   ;
1999   C6F9   CD40C7           CALL    RHED1   ;READ THAT MANY BYTES
2000   C6FC   DA02C7           JC      TERR    ;IF ERROR OR ESC
2001   C6FF   CAF3C6           JZ      RTAP2   ;RD OK--READ SOME MORE
2002                   ;
2003                   ;  ERROR RETURN
2004                   ;
2005   C702   AF       TERR:   XRA     A
2006   C703   37               STC             ;SET ERROR FLAGS
2007   C704   C30DC7           JMP     RTOF1
2008                   ;
2009                   ;
2010   C707   0601     TOFF:   MVI     B,1
2011   C709   CDEFC7           CALL    DELAY
2012   C70C   AF       RTOFF:  XRA     A
2013   C70D   D306     RTOF1:  OUT     TAPPT
2014   C70F   D1               POP     D       ;RETURN BYTE COUNT
2015   C710   C9               RET
2016                   ;
2017                   ;
2018   C711            DCRCT   EQU     $       ;COMMON RTN TO COUNT DOWN BLK LENGTHS
2019   C711   AF               XRA     A       ;CLR FOR LATER TESTS
2020   C712   47               MOV     B,A     ;SET THIS BLK LEN=256
2021   C713   B2               ORA     D       ;IS AMNT LEFT < 256
2022   C714   C21CC7           JNZ     DCRC2   ;NO--REDUCE AMNT BY 256
2023   C717   B3               ORA     E       ;IS ENTIRE COUNT ZERO
2024   C718   C8               RZ              ;ALL DONE--ZERO=THIS CONDITION
2025   C719   43               MOV     B,E     ;SET THIS BLK LEN TO AMNT REMAINING
2026   C71A   5A               MOV     E,D     ;MAKE ENTIRE COUNT ZERO NOW
2027   C71B   C9               RET             ;ALL DONE (NON-ZERO FLAG)
2028   C71C            DCRC2   EQU     $       ;REDUCE COUNT BY 256
2029   C71C   15               DCR     D       ;DROP BY 256
2030   C71D   B7               ORA     A       ;FORCE NON-ZERO FLAG
20311
2032 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2033+                                                      19:09  05/27/2017
2034+                                                                                      PAGE 36
2035
2036
2037
2038   C71E   C9               RET             ;NON-ZERO=NOT DONE YET (BLK LEN=256)
2039                   ;
2040                   ;
2041                   ;   READ THE HEADER
2042                   ;
2043   C71F   060A     RHEAD:  MVI     B,10    ;FIND 10 NULLS
2044   C721   CD59C7   RHEA1:  CALL    STAT
2045   C724   D8               RC              ;IF ESCAPE
2046   C725   DB07             IN      TDATA   ;IGNORE ERROR CONDITIONS
2047   C727   B7               ORA     A       ;ZERO?
2048   C728   C21FC7           JNZ     RHEAD
2049   C72B   05               DCR     B
2050   C72C   C221C7           JNZ     RHEA1   ;LOOP UNTIL 10 IN A ROW
2051                   ;
2052                   ;    WAIT FOR THE START CHARACTER
2053                   ;
2054   C72F   CD6CC7   SOHL:   CALL    TAPIN
2055   C732   D8               RC              ;ERROR OR ESCAPE
2056   C733   FE01             CPI     1       ;ARE WE AT THE 01 YET (START CHAR)
2057   C735   DA2FC7           JC      SOHL    ;NO, BUT STIL ZEROES
2058   C738   C21FC7           JNZ     RHEAD   ;NO, LOOK FOR ANOTHER 10 NULLS
2059                   ;
2060                   ;    WE HAVE  10 (OR MORE) NULLS FOLLOWED IMMEDIATELY
2061                   ;    BY AN 01.  NOW READ THE HEADER.
2062                   ;
2063   C73B   211CC8           LXI     H,THEAD ;POINT TO BUFFER
2064   C73E   0610             MVI     B,HLEN  ;LENGTH TO READ
2065                   ;
2066   C740            RHED1   EQU     $       ;RD A BLOCK INTO HL FOR B BYTES
2067   C740   0E00             MVI     C,0     ;INIT THE CRC
2068   C742            RHED2   EQU     $       ;LOOP HERE
2069   C742   CD6CC7           CALL    TAPIN   ;GET A BYTE
2070   C745   D8               RC
2071   C746   77               MOV     M,A     ;STORE IT
2072   C747   23               INX     H       ;INCREMENT ADDRESS
2073   C748   CDA6C7           CALL    DOCRC   ;GO COMPUTE THE CRC
2074   C74B   05               DCR     B       ;WHOLE HEADER YET?
2075   C74C   C242C7           JNZ     RHED2   ;DO ALL THE BYTES
2076                   ;
2077                   ;   THIS ROUTINE GETS THE NEXT BYTE AND COMPARES IT
2078                   ; TO THE VALUE IN REGISTER C.  THE FLAGS ARE SET ON
2079                   ; RETURN.
2080                   ;
2081   C74F   CD6CC7           CALL    TAPIN   ;GET CRC BYTE
2082   C752   A9               XRA     C       ;CLR CARRY AND SET ZERO IF MATCH, ELSE NON-ZERO
2083   C753   C8               RZ              ;CRC IS FINE
2084   C754   3A11C8           LDA     IGNCR   ;BAD CRC, SHD WE STILL ACCEPT IT
2085   C757   3C               INR     A       ;SEE IF IT WAS FF, IF FF THEN ZERO SAYS IGN ERR
2086                   ;   NOW, CRC ERR DETECTION DEPENDS ON IGNCR.
2087   C758   C9               RET
2088                   ;
20891
2090 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2091+                                                      19:09  05/27/2017
2092+                                                                                      PAGE 37
2093
2094
2095
2096                   ;    THIS ROUTINE GETS THE NEXT AVAILABLE BYTE FROM THE
2097                   ;  TAPE.  WHILE WAITING FOR THE BYTE THE KEYBOARD IS TESTED
2098                   ;  FOR AN ESC COMMAND.  IF RECEIVED THE TAPE LOAD IS
2099                   ;  TERMINATED AND A RETURN TO THE COMMAND MODE IS MADE.
2100                   ;
2101   C759   DB06     STAT:   IN      TAPPT   ;TAPE STATUS PORT
2102   C75B   2F               CMA             ;*UM* MITS ACR USES ACTIVE LOW
2103   C75C   E601             ANI     TDR
2104   C75E   C0               RNZ
2105   C75F   CD1FC0           CALL    SINP    ;CHECK INPUT
2106   C762   CA59C7           JZ      STAT    ;NOTHING THERE YET
2107   C765   E67F             ANI     7FH     ;CLEAR PARITY 1ST
2108   C767   C259C7           JNZ     STAT    ;EITHER MODE OR CTL-@
2109   C76A   37               STC             ;SET ERROR FLAG
2110   C76B   C9               RET             ;AND RETURN
2111                   ;
2112                   ;
2113                   ;
2114   C76C   CD59C7   TAPIN:  CALL    STAT    ;WAIT UNTIL A CHARACTER IS AVAILABLE
2115   C76F   D8               RC
2116                   ;
2117   C770   DB06     TREDY:  IN      TAPPT   ;TAPE STATUS
2118   C772   E618             ANI     TFE+TOE ;DATA ERROR?
2119   C774   DB07             IN      TDATA   ;GET THE DATA
2120   C776   C8               RZ              ;IF NO ERRORS
2121   C777   37               STC             ;SET ERROR FLAG
2122   C778   C9               RET
2123                   ;
2124                   ;
2125                   ;  THIS ROUTINE GETS THE CORRECT UNIT FOR SYSTEM WRITES
2126   C779   CDDCC7   WFBLK:  CALL    GTUNT   ;SET UP A WITH UNIT AND SPEED
2127                   ;
2128                   ;
2129                   ;
2130                   ;       WRITE TAPE BLOCK ROUTINE
2131                   ;
2132                   ;   ON ENTRY:   A   HAS UNIT AND SPEED
2133                   ;              HL   HAS POINTER TO HEADER
2134                   ;
2135                   ;
2136   C77C            WTAPE   EQU     $       ;HERE TO WRITE TAPE
2137   C77C   E5               PUSH    H       ;SAVE HEADER ADDRESS
2138   C77D   CDADC7           CALL    WHEAD   ;TURN ON, THEN WRITE HDR
2139   C780   E1               POP     H
2140   C781   110700           LXI     D,BLKOF ;OFFSET TO BLOCK SIZE IN HEADER
2141   C784   19               DAD     D       ;HL POINT TO BLOCK SIZE
2142   C785   5E               MOV     E,M
2143   C786   23               INX     H
2144   C787   56               MOV     D,M     ;DE HAVE SIZE
2145   C788   23               INX     H
2146   C789   7E               MOV     A,M
21471
2148 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2149+                                                      19:09  05/27/2017
2150+                                                                                      PAGE 38
2151
2152
2153
2154   C78A   23               INX     H
2155   C78B   66               MOV     H,M
2156   C78C   6F               MOV     L,A     ;HL HAVE STARTING ADDRESS
2157                   ;
2158                   ;    THIS ROUTINE WRITES ONE PHYSICAL BLOCK ON THE
2159                   ;  TAPE "DE" BYTES LONG FROM ADDRESS "HL".
2160                   ;
2161                   ;
2162   C78D            WTAP1   EQU     $       ;HERE FOR THE EXTRA PUSH
2163   C78D   E5               PUSH    H       ;A DUMMY PUSH FOR LATER EXIT
2164   C78E            WTAP2   EQU     $       ;LOOP HERE UNTIL ENTIRE AMOUNT READ
2165   C78E   CD11C7           CALL    DCRCT   ;DROP COUNT IN DE AND SET UP B W/LEN THIS BLK
2166   C791   CA07C7           JZ      TOFF    ;RETURNS ZERO IF ALL DONE
2167   C794   CDC1C7           CALL    WTBL    ;WRITE BLOCK FOR BYTES IN B (256)
2168   C797   C38EC7           JMP     WTAP2   ;LOOP UNTIL ALL DONE
2169                   ;
2170                   ;
2171   C79A   F5       WRTAP:  PUSH    PSW
2172   C79B   DB06     WRWAT:  IN      TAPPT   ;TAPE STATUS
2173   C79D   2F               CMA             ;*UM* MITS ACR USES ACTIVE LOW
2174   C79E   E680             ANI     TTBE    ;IS TAPE READY FOR A CHAR YET
2175   C7A0   CA9BC7           JZ      WRWAT   ;NO--WAIT
2176   C7A3   F1               POP     PSW     ;YES--RESTORE CHAR TO OUTPUT
2177   C7A4   D307             OUT     TDATA   ;SEND CHAR TO TAPE
2178                   ;
2179   C7A6            DOCRC   EQU     $       ;A COMMON CRC COMPUTATION ROUTINE
2180   C7A6   91               SUB     C
2181   C7A7   4F               MOV     C,A
2182   C7A8   A9               XRA     C
2183   C7A9   2F               CMA
2184   C7AA   91               SUB     C
2185   C7AB   4F               MOV     C,A
2186   C7AC   C9               RET             ;ONE  BYTE NOW WRITTEN
2187                   ;
2188                   ;
2189                   ;   THIS ROUTINE WRITES THE HEADER POINTED TO BY
2190                   ;   HL TO THE TAPE.
2191                   ;
2192   C7AD            WHEAD   EQU     $       ;HERE TO 1ST TURN ON THE TAPE
2193   C7AD   CDEBC7           CALL    WTON    ;TURN IT ON, THEN WRITE HEADER
2194   C7B0   1632             MVI     D,50    ;WRITE 50 ZEROS
2195   C7B2   AF       NULOP:  XRA     A
2196   C7B3   CD9AC7           CALL    WRTAP
2197   C7B6   15               DCR     D
2198   C7B7   C2B2C7           JNZ     NULOP
2199                   ;
2200   C7BA   3E01             MVI     A,1
2201   C7BC   CD9AC7           CALL    WRTAP
2202   C7BF   0610             MVI     B,HLEN  ;LENGTH TO WRITE OUT
2203                   ;
2204   C7C1   0E00     WTBL:   MVI     C,0     ;RESET CRC BYTE
22051
2206 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2207+                                                      19:09  05/27/2017
2208+                                                                                      PAGE 39
2209
2210
2211
2212   C7C3   7E       WLOOP:  MOV     A,M     ;GET CHARACTER
2213   C7C4   CD9AC7           CALL    WRTAP   ;WRITE IT TO THE TAPE
2214   C7C7   05               DCR     B
2215   C7C8   23               INX     H
2216   C7C9   C2C3C7           JNZ     WLOOP
2217   C7CC   79               MOV     A,C     ;GET CRC
2218   C7CD   C39AC7           JMP     WRTAP   ;PUT IT ON THE TAPE AND RETURN
2219                   ;
2220                   ;
2221                   ;   THIS ROUTINE COMPARES THE HEADER IN THEAD TO
2222                   ;   THE USER SUPPLIED HEADER IN ADDRESS HL.
2223                   ;   ON RETURN IF ZERO IS SET THE TWO NAMES COMPARED
2224                   ;
2225   C7D0   0605     DHCMP:  MVI     B,5
2226   C7D2   1A       DHLOP:  LDAX    D
2227   C7D3   BE               CMP     M
2228   C7D4   C0               RNZ
2229   C7D5   05               DCR     B
2230   C7D6   C8               RZ              ;IF ALL FIVE COMPARED
2231   C7D7   23               INX     H
2232   C7D8   13               INX     D
2233   C7D9   C3D2C7           JMP     DHLOP
2234                   ;
2235   C7DC            GTUNT   EQU     $       ;SET A=SPEED + UNIT
2236   C7DC   3A54C8           LDA     FNUMF   ;GET UNIT
2237   C7DF   B7               ORA     A       ;SEE WHICH UNIT
2238   C7E0   3A0DC8           LDA     TSPD    ;BUT 1ST GET SPEED
2239   C7E3   C2E8C7           JNZ     GTUN2   ;MAKE IT UNIT TWO
2240   C7E6   C640             ADI     TAPE2   ;THIS ONCE=UNIT 2, TWICE=UNIT 1
2241   C7E8   C640     GTUN2:  ADI     TAPE2   ;UNIT AND SPEED NOW SET IN A
2242   C7EA   C9               RET             ;ALL DONE
2243                   ;
2244   C7EB   0604     WTON:   MVI     B,4     ;SET LOOP DELAY  (BIT LONGER ON A WRITE)
2245   C7ED            TON     EQU     $       ;HERE TO TURN A TAPE ON THEN DELAY
2246   C7ED   D306             OUT     TAPPT   ;GET TAPE MOVING, THEN DELAY
2247                   ;
2248   C7EF   110000   DELAY:  LXI     D,0
2249   C7F2   1B       DLOP1:  DCX     D
2250   C7F3   7A               MOV     A,D
2251   C7F4   B3               ORA     E
2252   C7F5   C2F2C7           JNZ     DLOP1
2253   C7F8   05               DCR     B
2254   C7F9   C2EFC7           JNZ     DELAY
2255   C7FC   C9               RET
2256                   ;
2257                   ;
2258                   ;**** -- END OF PROGRAM--
2259                   ;
2260                   ;
2261                   ;
2262                   ;
22631
2264 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2265+                                                      19:09  05/27/2017
2266+                                                                                      PAGE 40
2267
2268
2269
2270                   ;    S Y S T E M    E Q U A T E S
2271                   ;
2272                   ;
2273                   ;          VDM PARAMETERS
2274                   ;
2275   CC00            VDMEM   EQU     0CC00H  ;VDM SCREEN MEMORY
2276                   ;
2277                   ;
2278                   ;            KEYBOARD SPECIAL KEY ASSIGNMENTS
2279                   ;
2280                   ;  THESE DEFINITIONS ARE DESIGNED TO ALLOW
2281                   ;  COMPATABILITY WITH SOLOS(TM). THESE ARE THE
2282                   ;  SAME KEYS WITH BIT 7 (X'80') STRIPPED OFF.
2283                   ;
2284   001A            DOWN    EQU     1AH     ;CTL Z
2285   0017            UP      EQU     17H     ;CTL W
2286   0001            LEFT    EQU     01H     ;CTL A
2287   0013            RIGHT   EQU     13H     ;CTL S
2288   000B            CLEAR   EQU     0BH     ;CTL K
2289   000E            HOME    EQU     0EH     ;CTL N
2290   0000            MODE    EQU     00H     ;CTL-@
2291                   ;BACKS   EQU     5FH     ;BACKSPACE
2292   0008            BACKS   EQU     08H     ;*UM*
2293   000A            LF      EQU     10
2294   000D            CR      EQU     13
2295   0020            BLANK   EQU     ' '
2296   0020            SPACE   EQU     BLANK
2297   0018            CX      EQU     'X'-40H
2298   001B            ESC     EQU     1BH
2299                   ;
2300                   ;          PORT ASSIGNMENTS
2301                   ;
2302   0000            STAPT   EQU     0       ;STATUS PORT GENERAL
2303                   ;STKBD   EQU     STAPT   ;PROCTEC 3P+S
2304   0004            STKBD   EQU     4       ;*UM* MITS PIO
2305   0001            SDATA   EQU     1       ;SERIAL DATA
2306   0012            SIO2S   EQU     18      ;*UM* STATUS SIO2 B
2307   0013            SIO2D   EQU     19      ;*UM* DATA SIO2 B
2308   0002            PDATA   EQU     2       ;PARALLEL DATA
2309                   ;KDATA   EQU     3       ;KEYBOARD DATA PROCTEC 3P+S
2310   0005            KDATA   EQU     5       ;*UM* KEYBOARD DATA MITS PIO
2311   00C8            DSTAT   EQU     0C8H    ;VDM CONTROL PORT
2312                   ;TAPPT   EQU     0FAH    ;TAPE STATUS PORT PROCTEC SOL-20
2313   0006            TAPPT   EQU     06H     ;*UM* TAPE STATUS PORT MITS ACR
2314                   ;TDATA   EQU     0FBH    ;TAPE DATA PORT PROCTEC SOL-20
2315   0007            TDATA   EQU     07H     ;*UM* TAPE DATA PORT MITS ACR
2316   00FF            SENSE   EQU     0FFH    ;SENSE SWITCHES
2317                   ;
2318                   ;
2319                   ;
2320                   ;          BIT ASSIGNMENT MASKS
23211
2322 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2323+                                                      19:09  05/27/2017
2324+                                                                                      PAGE 41
2325
2326
2327
2328                   ;
2329   0001            SCD     EQU     1       ;SERIAL CARRIER DETECT
2330   0002            SDSR    EQU     2       ;SERIAL DATA SET READY
2331   0004            SPE     EQU     4       ;SERIAL PARITY ERROR
2332   0008            SFE     EQU     8       ;SERIAL FRAMING ERROR
2333   0010            SOE     EQU     16      ;SERIAL OVERRUN ERROR
2334   0020            SCTS    EQU     32      ;SERIAL CLEAR TO SEND
2335                   ;SDR     EQU     64      ;SERIAL DATA READY PROCTEC 3P+S
2336   0001            SDR     EQU     1       ;*UM* SERIAL DATA READY MITS SIO
2337   0001            SDR2    EQU     1       ;*UM* SERIAL DATA READY MITS 2SIO
2338                   ;STBE    EQU     128     ;SERIAL TRANSMITTER BUFFER EMPTY PROCTEC 3P+S
2339   0080            STBE    EQU     128     ;*UM* SERIAL TRANSMITTER BUFFER EMPTY MITS SIO
2340   0002            STBE2   EQU     2       ;*UM* SERIAL TRANSMITTER BUFFER EMPTY MITS 2SIO
2341                   ;
2342   0001            KDR     EQU     1       ;KEYBOARD DATA READY
2343   0002            PDR     EQU     2       ;PARALLEL DATA READY
2344   0004            PXDR    EQU     4       ;PARALLEL DEVICE READY
2345                   ;TFE     EQU     8       ;TAPE FRAMING ERROR PROCTEC CUTS
2346   0010            TFE     EQU     16      ;*UM* TAPE FRAMING ERROR MITS ACR
2347                   ;TOE     EQU     16      ;TAPE OVERFLOW ERROR PROCTEC CUTS
2348   0008            TOE     EQU     8       ;*UM* TAPE OVERFLOW ERROR MITS ACR
2349                   ;TDR     EQU     64      ;TAPE DATA READY PROCTEC CUTS
2350   0001            TDR     EQU     1       ;*UM* TAPE DATA READY MITS ACR
2351   0080            TTBE    EQU     128     ;TAPE TRANSMITTER BUFFER EMPTY
2352                   ;
2353   0001            SOK     EQU     1       ;SCROLL OK FLAG
2354                   ;
2355   0080            TAPE1   EQU     80H     ;1=TURN TAPE ONE ON
2356   0040            TAPE2   EQU     40H     ;1=TURN TAPE TWO ON
2357                   ;
2358                   ;
2359                   ;
2360                   ;
2361                   ;       S Y S T E M   G L O B A L    A R E A
2362                   ;
2363   C800                    ORG    START+0800H ;RAM STARTS JUST AFTER ROM
2364                   ;
2365   C800            SYSRAM  EQU     $       ;START OF SYSTEM RAM
2366   CBFF            SYSTP   EQU     SYSRAM+3FFH ;STACK WORKS FM TOP DOWN
2367                   ;
2368                   ;
2369                   ;   PARAMETERS STORED IN RAM
2370                   ;
2371   C800            UIPRT:  DS      2       ;USER DEFINED INPUT RTN IF NON ZERO
2372   C802            UOPRT:  DS      2       ;USER DEFINED OUTPUT RTN IF NON ZERO
2373   C804            DFLTS:  DS      2       ;DEFAULT PSUEDO I/O PORTS
2374   C806            IPORT:  DS      1       ;CRNT INPUT PSUEDO PORT
2375   C807            OPORT:  DS      1       ;CRNT OUTPUT PSUEDO PORT
2376   C808            NCHAR:  DS      1       ;CURRENT CHARACTER POSITION
2377   C809            LINE:   DS      1       ;CURRENT LINE POSITION
2378   C80A            BOT:    DS      1       ;BEGINNING OF TEXT DISPLACEMENT
23791
2380 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2381+                                                      19:09  05/27/2017
2382+                                                                                      PAGE 42
2383
2384
2385
2386   C80B            SPEED:  DS      1       ;SPEED CONTROL BYTE
2387   C80C            ESCFL:  DS      1       ;ESCAPE FLAG CONTROL BYTE
2388   C80D            TSPD:   DS      1       ;CURRENT TAPE SPEED
2389   C80E            INPTR:  DS      2       ;PTR TO NEXT CHAR POSITION IN INLIN
2390   C810            NUCNT:  DS      1       ;NUMBER OF NULLS AFTER CRLF
2391   C811            IGNCR:  DS      1       ;IGN CRC ERR FLAG, FF=IGN CRC ERRS, ELSE=NORMAL
2392                   ;
2393   C812                    DS      10      ;ROOM FOR FUTURE EXPANSION
2394                   ;
2395                   ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2396                   ;    T H I S   I S   T H E   H E A D E R   L A Y O U T    *
2397                   ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2398                   ;
2399   C81C            THEAD:  DS      5       ;NAME
2400   C821                    DS      1       ;THIS BYTE MUST BE ZERO
2401   C822            HTYPE:  DS      1       ;TYPE
2402   C823            BLOCK:  DS      2       ;BLOCK SIZE
2403   C825            LOADR:  DS      2       ;LOAD ADDRESS
2404   C827            XEQAD:  DS      2       ;AUTO EXECUTE ADDRESS
2405   C829            HSPR:   DS      3       ;SPARES
2406                   ;
2407   0010            HLEN    EQU     $-THEAD ;LENGTH OF HEADER
2408   0007            BLKOF   EQU     BLOCK-THEAD ;OFFSET TO BLOCK SIZE
2409   C82C            DHEAD:  DS      HLEN    ;A DUMMY HDR FOR COMPARES WHILE RD'ING
2410                   ;
2411                   ;
2412   C83C            CUTAB:  DS      6*4     ;ROOM FOR UP TO 6 CUSTOM USER COMMANDS
2413                   ;
2414                   ;
2415   C854            FNUMF:  DS      1       ;FOR CURRENT FILE OPERATIONS
2416   C855            FCBAS:  DS      7       ;1ST FILE CONTROL BLOCK
2417   C85C            FCBA2:  DS      7       ;2ND FILE CONTROL BLOCK
2418   C863            FBUF1:  DS      2*256   ;SYSTEM FILE BUFFER BASE
2419   CA63                    DS      1       ;"BELL" (X'07') FLAGS START OF INPUT BFR
2420   CA64            INLIN:  DS      80      ;ROOM FOR THE INPUT LINE
2421   CAB4            USARE   EQU     $       ;START OF USER AREA
2422                   ;
2423                   ;   REMEMBER THAT THE STACK WORKS ITS WAY DOWN-FROM
2424                   ;   THE END OF THIS 1K RAM AREA.
2425                   ;
2426                   ; -*-
2427                           END
2428 NO PROGRAM ERRORS
24291
2430 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2431+                                                      19:09  05/27/2017
2432+                                                                                      PAGE 43
2433
2434
2435
2436                        SYMBOL TABLE
2437
2438  * 01
2439
2440  A      0007      ADOUT  C3D9      AINP   C022 *    ALOAD  C544
2441  AOUT   C01C *    ARET   C1C3 *    ARET1  C1C5      ARET2  C1CA
2442  B      0000      BACKS  0008      BLANK  0020      BLKOF  0007
2443  BLOCK  C823      BOPEN  C5DC      BOT    C80A      BOUT   C3F7
2444  C      0001      CHAR   C0B8      CHRLI  C56D      CLEAR  000B
2445  CLERA  C1DC      CLIN1  C123      CLIN2  C118      CLINE  C11D *
2446  COMN1  C215      COMND  C218      COMTA  C2BD      CONT   C264 *
2447  COPRC  C26A      CR     000D      CREM   C15F      CRLF   C342
2448  CSET   C576      CUR    C0F5      CURET  C1CE      CURSC  C0F3
2449  CUSE2  C5CF      CUSET  C5B9      CUTAB  C83C      CX     0018 *
2450  D      0002      DCRC2  C71C      DCRCT  C711      DEFLT  C494
2451  DELAY  C7EF      DFLTS  C804      DHCMP  C7D0      DHEAD  C82C
2452  DHLOP  C7D2      DISP0  C282      DISP1  C28B      DISPD  C595
2453  DISPT  C287      DLOOP  C3B6      DLOP1  C7F2      DLP1   C3C1
2454  DLP1A  C3D0      DOCRC  C7A6      DOWN   001A      DSTAT  00C8
2455  DUMP   C3AD      E      0003      ENLO1  C427      ENLO3  C444
2456  ENLOP  C418      ENTER  C414      EOFER  C5FB      EOFW   C627
2457  ERAS1  C0FF      ERAS3  C112      ERR1   C46B      ERR2   C46C
2458  ERRIT  C065      ERRM   C521      ERRO1  C070      ERROT  C06C
2459  ESC    001B      ESCFL  C80C      ESCS   C187      ESCSP  C190
2460  EXEC   C449      EXEC1  C44C      FBUF1  C863      FCBA2  C85C
2461  FCBAS  C855      FCLOS  C00A *    FDCOM  C291      FDCOU  C28E
2462  FNUMF  C854      FOPEN  C007 *    GCLI0  C227      GCLI1  C232
2463  GCLI2  C25F      GCLI3  C261      GCLIN  C239      GOBAC  C08F
2464  GOBK   C0A0      GTBYT  C671      GTUN2  C7E8      GTUNT  C7DC
2465  H      0004      HBOUT  C3DE      HCONV  C38B *    HCOV1  C39B
2466  HEOU1  C405      HEOUT  C3FC      HLEN   0010      HOME   000E
2467  HSPR   C829 *    HTYPE  C822      IGNCR  C811      INIT   C001 *
2468  INLIN  CA64      INPTR  C80E      IOPRC  C026      IPORT  C806
2469  ITAB   C309      KDATA  0005      KDR    0001      KREA1  C035
2470  L      0005      LEFT   0001      LF     000A      LFCB   C62F
2471  LFCB1  C63E      LINE   C809      LIST1  C535      LLIST  C52D
2472  LOADR  C825      M      0006      MODE   0000 *    NAME   C454
2473  NAME0  C451      NAME1  C459      NAOUT  C54C      NCHAR  C808
2474  NCOM   C2A3      NEXT   C0A4      NFIL   C480      NLOOP  C566
2475  NUCNT  C810      NULOP  C7B2      NULOT  C350      OCHAR  C0BC
2476  OK     C0E5      OPORT  C807      OTAB   C301      OUTH   C410
2477  OUTPR  C02E      PARIT  C052      PAROT  C05A      PBACK  C167
2478  PCLOS  C5FF      PCR    C170      PCUR   C138      PDATA  0002 *
2479  PDOWN  C0EF      PDR    0002 *    PERSE  C0F9      PESC   C181
2480  PHEAD  C6A2      PHOME  C109      PLEFT  C134      PLF    C175
2481  PLOAD  C6BB      PRIT   C13E      PROMP  C33A      PSCAN  C3A5
2482  PSTOR  C6B2      PSW    0006      PTAP1  C6CF      PUP    C12D
2483  PXDR   0004 *    RDBLK  C013 *    RDBYT  C00D *    RDNBL  C658 *
2484  RETRN  C004 *    RFBLK  C6C4      RHEA1  C721      RHEAD  C71F
2485  RHED1  C740      RHED2  C742      RIGHT  0013      RT1    C67C
2486  RTAP   C6F2      RTAP2  C6F3      RTAPE  C6C7      RTBYT  C642
24871
2488 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0
2489+                                                      19:09  05/27/2017
2490+                                                                                      PAGE 44
2491                              SYMBOL TABLE
2492
2493
2494  RTOF1  C70D      RTOFF  C70C      SBLK   C359      SBLK1  C35B
2495  SCD    0001 *    SCHR   C36C      SCHR1  C36E      SCONV  C378
2496  SCROL  C0D0 *    SCTS   0020 *    SDATA  0001      SDR    0001
2497  SDR2   0001      SDSR   0002 *    SECON  C1B8      SENSE  00FF
2498  SEROT  C047      SETAB  C311      SETCI  C5A1      SETCO  C5A5
2499  SETCR  C5B5      SETIN  C599      SETNU  C5B1      SETOT  C59D
2500  SETSP  C590      SETTY  C5A9      SETX   C1B0      SETXQ  C5AD
2501  SETY   C1B4      SFE    0008 *    SHE1   C381      SHEX   C37E
2502  SINP   C01F      SIO2D  0013      SIO2S  0012      SOE    0010 *
2503  SOHL   C72F      SOK    0001 *    SOUT   C019      SP     0006
2504  SPACE  0020      SPE    0004 *    SPEED  C80B      SREA1  C03E
2505  SROL   C0D4      STAPT  0000      START  C000      STAT   C759
2506  STBE   0080      STBE2  0002      STKBD  0004      STRTA  C1D7
2507  STRTB  C1F4      STRTC  C1FF      STRTD  C20F      STSPD  C594
2508  STUNT  C49C      STUP   C2AA      SYSRA  C800      SYSTP  CBFF
2509  TAERR  C510      TAPE1  0080      TAPE2  0040      TAPIN  C76C
2510  TAPPT  0006      TASPD  C58A      TBL    C2E2      TDATA  0007
2511  TDR    0001      TERE0  C5F8      TERE1  C5F7 *    TERE2  C5F6
2512  TERR   C702      TFE    0010      THEAD  C81C      TIMER  C09B
2513  TLIST  C527      TLOA2  C4AF *    TLOA3  C4BB      TLOAD  C4A1
2514  TOE    0008      TOFF   C707      TON    C7ED      TREDY  C770 *
2515  TSAVE  C4E0      TSPD   C80D      TSRCH  C0A6      TTBE   0080
2516  TXEQ   C4A0      UBUF   C5F1 *    UIPRT  C800      UOPRT  C802
2517  UP     0017      USARE  CAB4 *    VDAD   C14C      VDAD2  C149
2518  VDADD  C145      VDM01  C078      VDMEM  CC00      WFBLK  C779
2519  WHEAD  C7AD      WLOOP  C7C3      WRBLK  C016 *    WRBYT  C010 *
2520  WRTAP  C79A      WRWAT  C79B      WT1    C697      WTAP1  C78D
2521  WTAP2  C78E      WTAPE  C77C      WTBL   C7C1      WTBYT  C67F
2522  WTLP1  C3F1      WTON   C7EB      XEQAD  C827
2523
2524