1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 1
      


                   ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
                   ;
                   ; CUTER - MODIFIED TO USE MITS CARDS IN ALTAIR 8800
                   ;
                   ; PSEUDO DEVICE 0, CONSOLE: VDM-1 AT C8/CC00, KBD AT 4/5
                   ; PSEUDO DEVICE 1, SERIAL:  MITS SIO REV. 1 AT 0/1
                   ; PSEUDO DEVICE 2, SERIAL:  MITS 2SIO CHANNEL B AT 18/19
                   ;
                   ; TAPE I/O MODIFIED TO USE MITS ACR SIO AT 6/7
                   ;
                   ; 03/02/2017 UDO MUNK    FIRST VERSION FOR RELEASE
                   ; 03/23/2017 UDO MUNK    USE MITS 2SIO CHANNEL B FOR PSEUDO 2
                   ; 03/27/2017 UDO MUNK    USE MITS ACR SIO FOR TAPE I/O
                   ; 06/27/2017 UDO MUNK    DON'T CLEAR TO EOL FOR CR, JUST ADVANCE LINE
                   ;
                   ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
                   ;
                   ;
                   ;
                   ;        CUTER(TM)
                   ;
                   ;                 COPYRIGHT (C) 1977
                   ;                 SOFTWARE TECHNOLOGY CORP.
                   ;                 P.O. BOX 5260
                   ;                 SAN MATEO, CA 94402
                   ;                 (415) 349-8080
                   ;
                   ;    A L L    R I G H T S   R E S E R V E D ! ! !
                   ;
                   ;
                   ;        VERSION  1.3
                   ;                 77-03-27
                   ;
                   ;
                   ;  THIS PROGRAM IS DESIGNED TO BE A STANDALONE CUTS
                   ;  OPERATING SYSTEM. CUTER IS DESIGNED TO BE READ IN FROM
                   ;  CASSETTE TAPE OR TO BE RESIDENT IN READ-ONLY-MEMORY.
                   ;  CUTER SUPPORTS VARIOUS DEVICES INCLUDING SERIAL,
                   ;  PARALLEL, THE PROCESSOR TECHNOLOGY VDM(TM) AND UP TO
                   ;  TWO CUTS TAPE DRIVES.
                   ;
                   ;  CUTER(TM) HAS BEEN WRITTEN SO AS TO BE COMPATIBLE WITH
                   ;  SOLOS(TM).  THE FOLLOWING KEYS ARE USED BY CUTER(TM)
                   ;  IN PLACE OF THE SPECIAL KEYS ON THE SOL KEYBOARD:
                   ;
                   ;     CURSOR UP       CTL-W
                   ;     CURSOR LEFT     CTL-A
                   ;     CURSOR RIGHT    CTL-S
                   ;     CURSOR DOWN     CTL-Z
                   ;     CURSOR HOME     CTL-N
                   ;     CLEAR SCREEN    CTL-K
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 2
      


                   ;     MODE            CTL-@
                   ;
                   ;
                   ;
   C000                    ORG     0C000H
                   ;
                   ;
                   ;   AUTO-STARTUP CODE
                   ;
   C000   7F       START:  MOV     A,A     ;SHOW THIS IS CUTER (SOLOS=00)
                   ;      THIS BYTE ALLOWS AUTOMATIC POWER ON ENTRY
                   ;      WHEN IN ROM SUPPORTING THIS HARDWARE FEATURE.
   C001   C3D7C1   INIT:   JMP     STRTA   ;SYSTEM RESTART ENTRY POINT
                   ;
                   ;   THESE JUMP POINTS ARE PROVIDED TO ALLOW COMMON ENTRY
                   ; LOCATIONS FOR ALL VERSIONS OF CUTER.  THEY ARE USED
                   ; EXTENSIVELY BY CUTS SYSTEM PROGRAMS AND IT IS RECOMMENDED
                   ; THAT USER ROUTINES ACCESS CUTER ROUTINES THROUGH THESE
                   ; POINTS ONLY!
                   ;
   C004   C318C2   RETRN:  JMP     COMND   ;RETURN TO CUTER COMMAND PROCESSOR
   C007   C3DCC5   FOPEN:  JMP     BOPEN   ;CASSETTE OPEN FILE ENTRY
   C00A   C3FFC5   FCLOS:  JMP     PCLOS   ;CASSETTE CLOSE FILE ENTRY
   C00D   C342C6   RDBYT:  JMP     RTBYT   ;CASSETTE READ BYTE ENTRY
   C010   C37FC6   WRBYT:  JMP     WTBYT   ;CASSETTE WRITE BYTE ENTRY
   C013   C3C7C6   RDBLK:  JMP     RTAPE   ;CASSETTE READ BLOCK ENTRY
   C016   C37CC7   WRBLK:  JMP     WTAPE   ;CASSETTE WRITE BLOCK ENTRY
                   ;
                   ;     SYSTEM I/O ENTRY POINTS
                   ;
                   ;  THESE FOUR ENTRY POINTS ARE USED TO EITHER INPUT
                   ;  OR OUTPUT TO CUTER PSUEDO PORTS.
                   ;  THESE PSUEDO PORTS ARE AS FOLLOWS:
                   ;
                   ;  PORT   INPUT              OUTPUT
                   ;  ----   -----------------  ---------------------
                   ;   0     KEYBOARD INPUT     BUILT-IN VDM DRIVER
                   ;         ACTUAL PORT 3      PORT C8, MEMORY FROM CC00
                   ;   1     SERIAL PORT        SERIAL PORT
                   ;         ACTUAL PORT 1      ACTUAL PORT 1
                   ;   2     PARALLEL PORT      PARALLEL PORT
                   ;         ACTUAL PORT 2      ACTUAL PORT 2
                   ;   3     USER'S INPUT RTN   USER'S OUTPUT ROUTINE
                   ;
                   ;  STATUS FOR ACTUAL PORTS 1, 2 AND 3 IS VIA ACTUAL
                   ;  PORT 0.  THE BITS OF PORT ZERO ARE DEFINED AS FOLLOWS:
                   ;
                   ;   :     :     :     :     :     :---- : --- : --- :
                   ;   : TBE : RDA :     :     :     :PXDR : PDR : KDR :
                   ; BIT  7     6     5     4     3     2     1     0
                   ;
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 3
      


                   ;  WHERE:
                   ;    TBE    1=TRANSMITTER BUFFER EMPTY (SERIAL)
                   ;    RDA    1=READER DATA AVAILABLE (SERIAL)
                   ;    ----
                   ;    PXDR   0=PARALLEL EXTERNAL DEVICE READY
                   ;    ---
                   ;    PDR    0=PARALLEL DATA READY
                   ;    ---
                   ;    KDR    0=KEYBOARD DATA READY
                   ;
                   ;
                   ;
                   ;
                   ;  NOTE: SOUT AND SINP ARE "LDA" INSTRUCTIONS.
                   ;        THIS FACT IS USED TO ALLOW ACCESS TO THE
                   ;        BYTES "OPORT" AND "IPORT" DYNAMICALLY.
                   ;        THESE MUST REMAIN "LDA" INSTRUCTIONS!!!!!
                   ;
   C019   3A07C8   SOUT:   LDA     OPORT   ;OUTPUT VIA STANDARD OUTPUT PSUEDO PORT
   C01C   C32EC0   AOUT:   JMP     OUTPR   ;OUTPUT VIA PSUEDO PORT SPECIFIED IN REG A
   C01F   3A06C8   SINP:   LDA     IPORT   ;INPUT VIA STANDARD INPUT PSUEDO PORT
   C022            AINP    EQU     $       ;INPUT VIA PSUEDO PORT SPECIFIED IN REG A
                   ; -----------END OF SYSTEM ENTRY POINTS----------
                   ;
                   ;
                   ; AINP CONTINUES HERE (IT COULD HAVE BEEN A "JMP" THOUGH)
   C022   E5               PUSH    H       ;SAVE HL FM ENTRY
   C023   2109C3           LXI     H,ITAB
                   ;
                   ;    THIS ROUTINE PROCESSES THE I/O REQUESTS
                   ;
   C026   E603     IOPRC:  ANI     3       ;KEEP REGISTER "A" TO FOUR VALUES
   C028   07               RLC             ;COMPUTE ENTRY ADDRESS
   C029   85               ADD     L
   C02A   6F               MOV     L,A     ;WE HAVE ADDRESS
   C02B   C387C2           JMP     DISPT   ;DISPATCH TO IT
                   ;
                   ;
   C02E            OUTPR   EQU     $       ;PROCESS OUTPUT REQUESTS
   C02E   E5               PUSH    H       ;SAVE REGS
   C02F   2101C3           LXI     H,OTAB  ;POINT TO OUTPUT DISPATCH TABLE
   C032   C326C0           JMP     IOPRC   ;DISPATCH FOR PROPER PSUEDO PORT
                   ;
                   ;
                   ;
                   ; CUTER SYSTEM I/O ROUTINES
                   ;
                   ;
                   ;    THIS ROUTINE IS A MODEL OF ALL INPUT ROUTINES WITHIN
                   ;  CUTER.  THE FIRST ROUTINE "KREA1" PERFORMS THE INPUT
                   ;  FROM THE STANDARD KEYBOARD ON PARALLEL PORT 3.
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 4
      


                   ;  ALL STANDARD INPUT DRIVERS RETURN EITHER THE CHARACTER
                   ;  WITH A NON-ZERO FLAG, OR JUST A ZERO FLAG INDICATING
                   ;  THAT NO CHARACTER IS AVAILABLE YET.  IT WILL BE THE
                   ;  RESPONSIBILITY OF THE USER TO LOOP WAITING FOR A
                   ;  CHARACTER, OR TO USE THE INPUT AS A STATUS REQUEST.
                   ;  WHEN A CHARACTER IS AVAILABLE, IT IS RETURNED IN REG A.
                   ;
                   ;  THE FOLLOWING KEYBOARD ROUTINE MAY BE USED AS A SAMPLE
                   ;  OF HOW TO WRITE A USER INPUT ROUTINE.
                   ;
                   ;         KEYBOARD INPUT ROUTINE
                   ;
                   ; MODIFIED SO THAT KBD STATUS PORT CAN BE DIFFERENT FROM SIO STATUS PORT
                   ; UDO MUNK
                   ;
   C035            KREA1   EQU     $       ;KEYBOARD READ ROUTINE
                   ;       IN      STAPT   ;GET STATUS WORD
   C035   DB04             IN      STKBD   ;*UM*
   C037   2F               CMA             ;INVERT IT FOR PROPER RETURN
   C038   E601             ANI     KDR     ;TEST NOT KEYBOARD DATA READY
   C03A   C8               RZ              ;ZERO IF NO CHARACTER RECEIVED
                   ;
   C03B   DB05             IN      KDATA   ;GET CHARACTER
   C03D   C9               RET             ;GO BACK WITH IT
                   ;
                   ;
                   ;
                   ;   SERIAL INPUT ROUTINE
                   ;
   C03E            SREA1   EQU     $       ;SERIAL INPUT ROUTINE
   C03E   DB00             IN      STAPT   ;GET STATUS
   C040   2F               CMA             ;*UM* MITS SIO FLAGS ARE ACTIVE LOW
   C041   E601             ANI     SDR     ;TEST FOR SERIAL DATA READY
   C043   C8               RZ              ;FLAGS ARE SET
                   ;
   C044   DB01             IN      SDATA   ;GET DATA BYTE
                   ;  IT IS UP TO THE CALLER TO STRIP PARITY IF DESIRED
   C046   C9               RET             ;WE HAVE IT
                   ;
                   ;
                   ;   SERIAL DATA OUTPUT
                   ;
                   ; MODIFIED SO THAT STATUS BIT CAN BE DEFINED AS ANY BIT
                   ; UDO MUNK
                   ;
   C047            SEROT   EQU     $       ;SERIAL OUTPUT ROUTINE
   C047   DB00             IN      STAPT   ;GET STATUS
                   ;        RAL             ;PUT HIGH BIT IN CARRY
                   ;        JNC     SEROT   ;LOOP UNTIL TRANSMITTER BUFFER IS EMPTY
   C049   E680             ANI     STBE    ;*UM*
   C04B   C247C0           JNZ     SEROT   ;*UM*
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 5
      


   C04E   78               MOV     A,B     ;GET THE CHARACTER BACK
   C04F   D301             OUT     SDATA   ;SEND IT OUT
   C051   C9               RET             ;AND WE'RE DONE
                   ;
                   ;
                   ; PARALLEL DATA INPUT
                   ;
                   ; MODIFIED TO USE 2SIO CHANNEL B
                   ; UDO MUNK
                   ;
   C052            PARIT   EQU     $       ;GET CHAR FM PARALLEL PORT
                   ;        IN      STAPT   ;STATUS
                   ;        CMA             ;INVERT FOR PROPER RETURN
                   ;        ANI     PDR     ;IS DATA READY?
                   ;        RZ              ;NO--JUST EXIT
                   ;        IN      PDATA   ;YES--GET CHAR THEN
                   ;        RET             ;THEN EXIT
   C052   DB12             IN      SIO2S   ;GET STATUS
   C054   E601             ANI     SDR2    ;TEST FOR SERIAL DATA READY
   C056   C8               RZ              ;FLAGS ARE SET
   C057   DB13             IN      SIO2D   ;GET DATA BYTE
   C059   C9               RET             ;WE HAVE IT
                   ;
                   ;
                   ;  PARALLEL DATA OUTPUT ROUTINE
                   ;
                   ; MODIFIED TO USE 2SIO CHANNEL B
                   ; UDO MUNK
                   ;
   C05A            PAROT   EQU     $       ;OUTPUT CHAR TO PARALLEL PORT
                   ;        IN      STAPT   ;STATUS
                   ;        ANI     PXDR    ;IS EXTERNAL DEVICE READY?
                   ;        JNZ     PAROT   ;NO--WAIT TIL IT IS
                   ;        MOV     A,B     ;GET CHAR
                   ;        OUT     PDATA   ;SEND DATA NOW
                   ;        RET             ;DONE
   C05A   DB12             IN      SIO2S   ;GET STATUS
   C05C   E602             ANI     STBE2   ;DEVICE READY ?
   C05E   CA5AC0           JZ      PAROT   ;NO, WAIT
   C061   78               MOV     A,B     ;GET THE CHARACTER BACK
   C062   D313             OUT     SIO2D   ;SEND IT OUT
   C064   C9               RET             ;AND WE'RE DONE
                   ;
                   ;
                   ; USER DEFINED INPUT/OUTPUT ROUTINES
   C065            ERRIT   EQU     $       ;USER INPUT ROUTINE
   C065   E5               PUSH    H       ;SAVE ORIG HL
   C066   2A00C8           LHLD    UIPRT   ;GET USER'S RTN ADDR
   C069   C370C0           JMP     ERRO1   ;MERGE TO VERIFY THE ADDR
                   ;
   C06C            ERROT   EQU     $       ;USER OUTPUT ROUTINE
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 6
      


   C06C   E5               PUSH    H       ;SAVE ORIG HL
   C06D   2A02C8           LHLD    UOPRT   ;GET USER'S RTN ADDR
   C070            ERRO1   EQU     $       ;WE MERGE HERE TO VFY ADDR
   C070   7D               MOV     A,L     ;ZERO=UNDEFINED
   C071   B4               ORA     H       ;IS IT?
   C072   C28BC2           JNZ     DISP1   ;NO--VALID--OFF TO IT
   C075   C30FC2           JMP     STRTD   ;RESET I/O PORTS AND BACK TO COMMAND MODE
                   ;
                   ;
                   ;
                   ;                  VIDEO DISPLAY ROUTINES
                   ;
                   ;
                   ;  THESE ROUTINES ALLOW FOR STANDARD VIDEO TERMINAL
                   ;  OPERATIONS.  ON ENTRY, THE CHARACTER FOR OUTPUT IS IN
                   ;  REGISTER B AND ALL REGISTERS ARE UNALTERED ON RETURN.
                   ;
                   ;
                   ;
   C078            VDM01   EQU     $       ;VDM OUTPUT DRIVER
   C078   E5               PUSH    H       ;SAVE HL
   C079   D5               PUSH    D       ;SAVE DE
   C07A   C5               PUSH    B
                   ;
                   ;  PROCESS ESC SEQUENCE IF ANY
                   ;
   C07B   3A0CC8           LDA     ESCFL   ;GET ESCAPE FLAG
   C07E   B7               ORA     A
   C07F   C287C1           JNZ     ESCS    ;IF NON ZERO GO PROCESS THE REST OF THE SEQUENCE
                   ;
   C082   78               MOV     A,B     ;GET CHAR
   C083   E67F             ANI     7FH     ;CLR HI BIT IN CASE
   C085   47               MOV     B,A     ;USE CHAR STRIPPED OF HI BIT FOR COMPATABILITY
   C086   CAA0C0           JZ      GOBK    ;MAKE A QUICK EXIT FOR A NULL
                   ;
   C089   21E2C2           LXI     H,TBL
   C08C   CDA6C0           CALL    TSRCH   ;GO PROCESS
                   ;
   C08F            GOBACK  EQU     $       ;RESET CURSOR AND DELAY
   C08F   CD45C1           CALL    VDADD   ;GET SCRN ADDR
   C092   7E               MOV     A,M     ;GET CHAR
   C093   F680             ORI     80H     ;INVERSE VIDEO
   C095   77               MOV     M,A     ;CURSOR IS NOW THERE
   C096   2A0AC8           LHLD    SPEED-1 ;GET DELAY SPEED
   C099   2C               INR     L       ;MAKE IT DEFINITELY NON-ZERO
   C09A   AF               XRA     A       ;DELAY ENDS WHEN H=ZERO
   C09B   2B       TIMER:  DCX     H       ;LOOP FOR DELAY AMNT
   C09C   BC               CMP     H       ;IS IT DONE YET
   C09D   C29BC0           JNZ     TIMER   ;NO--KEEP DELAYING
   C0A0   C1       GOBK:   POP     B
   C0A1   D1               POP     D       ;RESTORE ALL REGISTERS
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 7
      


   C0A2   E1               POP     H
   C0A3   C9               RET             ;EXIT FROM VDMOT
                   ;
                   ;
   C0A4            NEXT    EQU     $       ;GO TO NEXT CHR
   C0A4   23               INX     H
   C0A5   23               INX     H
                   ;
                   ;  THIS ROUTINE SEARCHES FOR A MATCH OF THE CHAR IN "B"
                   ;  TO THE CHAR IN THE TBL POINTED TO BY HL.
                   ;
   C0A6   7E       TSRCH:  MOV     A,M     ;GET CHR FROM TABLE
   C0A7   B7               ORA     A       ;SEE IF END OF TBL
   C0A8   CAB8C0           JZ      CHAR    ;ZERO IS THE LAST
   C0AB   B8               CMP     B       ;TEST THE CHR
   C0AC   23               INX     H       ;POINT FORWARD
   C0AD   C2A4C0           JNZ     NEXT
   C0B0   E5               PUSH    H       ;FOUND ONE...SAVE ADDRESS
   C0B1   CD5FC1           CALL    CREM    ;REMOVE CURSOR
   C0B4   E3               XTHL            ;RESTORE ADDR OF CHAR ENTRY IN TBL
   C0B5   C387C2           JMP     DISPT   ;DISPATCH FOR CURSOR CONTROL
                   ;
                   ;
   C0B8            CHAR    EQU     $       ;WE HAVE A CHAR
   C0B8   78               MOV     A,B     ;GET CHARACTER
   C0B9   FE7F             CPI     7FH     ;IS IT A DEL?
   C0BB   C8               RZ              ;GO BACK IF SO
                   ;
                   ;
                   ;
   C0BC   CD45C1   OCHAR:  CALL    VDADD   ;GET SCREEN ADDRESS
   C0BF   70               MOV     M,B     ;PUT CHR ON SCREEN
   C0C0   3A08C8           LDA     NCHAR   ;GET CHARACTER POSITION
   C0C3   FE3F             CPI     63      ;END OF LINE?
   C0C5   DAE5C0           JC      OK
   C0C8   3A09C8           LDA     LINE
   C0CB   FE0F             CPI     15      ;END OF SCREEN?
   C0CD   C2E5C0           JNZ     OK
                   ;
                   ;   END OF SCREEN...ROLL UP ONE LINE
                   ;
   C0D0   AF       SCROLL: XRA     A
   C0D1   3208C8           STA     NCHAR   ;BACK TO FIRST CHAR POSITION
   C0D4   4F       SROL:   MOV     C,A
   C0D5   CD4CC1           CALL    VDAD    ;CALCULATE LINE TO BE BLANKED
   C0D8   AF               XRA     A
   C0D9   CD23C1           CALL    CLIN1   ;CLEAR IT
   C0DC   3A0AC8           LDA     BOT
   C0DF   3C               INR     A
   C0E0   E60F             ANI     0FH
   C0E2   C312C1           JMP     ERAS3
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 8
      


                   ;
                   ;   INCREMENT LINE COUNTER IF NECESSARY
                   ;
   C0E5   3A08C8   OK:     LDA     NCHAR   ;GET CHR POSITION
   C0E8   3C               INR     A
   C0E9   E63F             ANI     3FH     ;MOD 64
   C0EB   3208C8           STA     NCHAR   ;STORE THE NEW
   C0EE   C0               RNZ             ;MORE CHARS THIS LINE
   C0EF            PDOWN   EQU     $       ;MOVE CURSOR DOWN ONE LINE
   C0EF   3A09C8           LDA     LINE    ;GET THE LINE COUNT
   C0F2   3C               INR     A
   C0F3   E60F     CURSC:  ANI     0FH     ;MOD 15 INCREMENT
   C0F5   3209C8   CUR:    STA     LINE    ;STORE THE NEW
   C0F8   C9               RET
                   ;
                   ;    ERASE SCREEN
                   ;
   C0F9   2100CC   PERSE:  LXI     H,VDMEM ;POINT TO SCREEN
   C0FC   36A0             MVI     M,80H+' ' ;THIS IS THE CURSOR
                   ;
   C0FE   23               INX     H       ;NEXT CHAR
   C0FF            ERAS1   EQU     $       ;LOOP TO CLR SCRN
   C0FF   3620             MVI     M,' '   ;BLANK IT OUT
   C101   23               INX     H       ;NEXT SCRN LOC
   C102   7C               MOV     A,H     ;SEE IF DONE
   C103   FED0             CPI     0D0H    ;DID IT GO ABOVE VDM
   C105   DAFFC0           JC      ERAS1   ;NO--MORE
   C108   37               STC             ;SAY WE WANT TO DROP THRU TO ERAS3
                   ;
   C109            PHOME   EQU     $       ;RESET CURSOR TO HOME
   C109   3E00             MVI     A,0     ;CLEAR, LEAVE CARRY AS IS
   C10B   3209C8           STA     LINE    ;ZERO LINE
   C10E   3208C8           STA     NCHAR   ;LEFT SIDE OF SCREEN
   C111   D0               RNC             ;THIS IS JUST A HOME OPERATION
                   ;
   C112   D3C8     ERAS3:  OUT     DSTAT   ;RESET SCROLL PARAMETERS
   C114   320AC8           STA     BOT     ;BEGINNING OF TEXT OFFSET
   C117   C9               RET
                   ;
                   ;
   C118            CLIN2   EQU     $       ;HERE TO SEE IF VDM OUTPUT
   C118   3A07C8           LDA     OPORT   ;GET CRNT OUTPUT PORT
   C11B   B7               ORA     A
   C11C   C0               RNZ             ;NOT VDM--DONE THEN
   C11D   CD45C1   CLINE:  CALL    VDADD   ;GET CURRENT SCREEN ADDRESS
   C120   3A08C8           LDA     NCHAR   ;CURRENT CURSOR POSITION
   C123   FE40     CLIN1:  CPI     64      ;NO MORE THAN 63
   C125   D0               RNC             ;ALL DONE
   C126   3620             MVI     M,' '   ;ALL SPACED OUT
   C128   23               INX     H
   C129   3C               INR     A
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 9
      


   C12A   C323C1           JMP     CLIN1   ;LOOP TO END OF LINE
                   ;
                   ;
                   ;  ROUTINE TO MOVE THE CURSOR UP ONE LINE
                   ;
   C12D   3A09C8   PUP:    LDA     LINE    ;GET LINE COUNT
   C130   3D               DCR     A
   C131   C3F3C0           JMP     CURSC   ;MERGE
                   ;
                   ;  MOVE CURSOR LEFT ONE POSITION
                   ;
   C134   3A08C8   PLEFT:  LDA     NCHAR
   C137   3D               DCR     A
   C138            PCUR    EQU     $       ;TAKE CARE OF CURSOR SAME LINE
   C138   E63F             ANI     03FH    ;LET CURSOR WRAP AROUND
   C13A   3208C8           STA     NCHAR   ;UPDATED CURSOR
   C13D   C9               RET
                   ;
                   ;     CURSOR RIGHT ONE POSITION
                   ;
   C13E   3A08C8   PRIT:   LDA     NCHAR
   C141   3C               INR     A
   C142   C338C1           JMP     PCUR
                   ;
                   ;   ROUTINE TO CALCULATE SCREEN ADDRESS
                   ;
                   ;   ENTRY AT:    RETURNS:
                   ;
                   ;         VDADD  CURRENT SCREEN ADDRESS
                   ;         VDAD2  ADDRESS OF CURRENT LINE, CHAR 'C'
                   ;         VDAD   LINE 'A', CHARACTER POSITION 'C'
                    
   C145   3A08C8   VDADD:  LDA     NCHAR   ;GET CHARACTER POSITION
   C148   4F               MOV     C,A     ;'C' KEEPS IT
   C149   3A09C8   VDAD2:  LDA     LINE    ;LINE POSITION
   C14C   6F       VDAD:   MOV     L,A     ;INTO 'L'
   C14D   3A0AC8           LDA     BOT     ;GET TEXT OFFSET
   C150   85               ADD     L       ;ADD IT TO THE LINE POSITION
   C151   0F               RRC             ;TIMES TWO
   C152   0F               RRC             ;MAKES FOUR
   C153   6F               MOV     L,A     ;L HAS IT
   C154   E603             ANI     3       ;MOD THREE FOR LATER
   C156   C6CC             ADI     VDMEM SHR 8 ;LOW SCREEN OFFSET
   C158   67               MOV     H,A     ;NOW H IS DONE
   C159   7D               MOV     A,L     ;TWIST L'S ARM
   C15A   E6C0             ANI     0C0H
   C15C   81               ADD     C
   C15D   6F               MOV     L,A
   C15E   C9               RET             ;H & L ARE NOW PERVERTED
                   ;
                   ;    ROUTINE TO REMOVE CURSOR
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 10
      


                   ;
   C15F   CD45C1   CREM:   CALL    VDADD   ;GET CURRENT SCREEN ADDRESS
   C162   7E               MOV     A,M
   C163   E67F             ANI     7FH     ;STRIP OFF THE CURSOR
   C165   77               MOV     M,A
   C166   C9               RET
                   ;
                   ;     ROUTINE TO BACKSPACE
                   ;
   C167   CD34C1   PBACK:  CALL    PLEFT
   C16A   CD45C1           CALL    VDADD   ;GET SCREEN ADDRESS
   C16D   3620             MVI     M,' '   ;PUT A BLANK THERE
   C16F   C9               RET
                   ;
                   ;     ROUTINE TO PROCESS A CARRIAGE RETURN
                   ;
   C170            PCR:    ;CALL    CLINE   ;CLEAR FROM CURRENT CURSOR TO END OF LINE
                   ;  NOTE THAT A COMES BACK=64 WHICH WILL BE CLEARED AT PCUR
   C170   3E40             MVI     A,64    ;*UM* JUST ADVANCE LINE
   C172   C338C1           JMP     PCUR    ;AND STORE THE NEW VALUE
                   ;
                   ;   ROUTINE TO PROCESS LINEFEED
                   ;
   C175   3A09C8   PLF:    LDA     LINE    ;GET LINE COUNT
   C178   3C               INR     A       ;NEXT LINE
   C179   E60F             ANI     15      ;SEE IF IT WRAPPED AROUND
   C17B   C2F5C0           JNZ     CUR     ;IT DID NOT--NO SCROLL
                   ;
   C17E   C3D4C0           JMP     SROL    ;SCROLL ONE LINE--CURSOR SOME POSITION
                   ;
                   ;     SET ESCAPE PROCESS FLAG
                   ;
   C181   3EFF     PESC:   MVI     A,(-1) AND 0FFH
   C183   320CC8           STA     ESCFL   ;SET FLAG
   C186   C9               RET
                   ;
                   ;       PROCESS ESCAPE SEQUENCE
                   ;
   C187   CD5FC1   ESCS:   CALL    CREM    ;REMOVE CURSOR
   C18A   CD90C1           CALL    ESCSP   ;PROCESS THE CHARACTER
   C18D   C38FC0           JMP     GOBACK
                   ;
   C190   3A0CC8   ESCSP:  LDA     ESCFL   ;GET ESCAPE FLAG
   C193   FEFF             CPI     (-1) AND 0FFH ;TEST FLAG
   C195   CAB8C1           JZ      SECOND
                   ;
                   ;  PROCESS THIRD CHR OF ESC SEQUENCE
                   ;
   C198   210CC8           LXI     H,ESCFL
   C19B   3600             MVI     M,0
   C19D   FE02             CPI     2
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 11
      


   C19F   DAB0C1           JC      SETX    ;SET X
   C1A2   CAB4C1           JZ      SETY    ;SET Y
   C1A5   FE08             CPI     8       ;SPECIAL SET SPEED
   C1A7   CA94C5           JZ      STSPD   ;YES--SET THE SPEED WITH IT THEN
   C1AA   FE09             CPI     9
   C1AC   DABCC0           JC      OCHAR   ;PUT IT ON THE SCREEN
   C1AF   C0               RNZ
                   ;
                   ;  TAB ABSOLUTE TO VALUE IN REG B
                   ;
   C1B0   78       SETX:   MOV     A,B
   C1B1   C338C1           JMP     PCUR
                   ;
                   ;  SET CURSOR TO LINE "B"
                   ;
   C1B4   78       SETY:   MOV     A,B
   C1B5   C3F3C0           JMP     CURSC
                   ;
                   ;
                   ;   PROCESS SECOND CHR OF ESC SEQUENCE
                   ;
   C1B8   78       SECOND: MOV     A,B
   C1B9   FE03             CPI     3
   C1BB   CACEC1           JZ      CURET
   C1BE   FE04             CPI     4
   C1C0   C2CAC1           JNZ     ARET2
                   ;
   C1C3   44       ARET:   MOV     B,H
   C1C4   4D               MOV     C,L     ;PRESENT SCREEN ADDRESS TO BC FOR RETURN
   C1C5   E1       ARET1:  POP     H       ;RETURN ADDRESS
   C1C6   D1               POP     D       ;OLD B
   C1C7   C5               PUSH    B
   C1C8   E5               PUSH    H
   C1C9   AF               XRA     A
   C1CA   320CC8   ARET2:  STA     ESCFL
   C1CD   C9               RET
                   ;
                   ;
                   ;     RETURN PRESENT SCREEN PARAMETERS IN BC
                   ;
   C1CE   2108C8   CURET:  LXI     H,NCHAR
   C1D1   46               MOV     B,M     ;CHARACTER POSITION
   C1D2   23               INX     H
   C1D3   4E               MOV     C,M     ;LINE POSITION
   C1D4   C3C5C1           JMP     ARET1
                   ;
                   ;
                   ;
                   ;                START UP SYSTEM
                   ;
                   ;   CLEAR SCREEN AND THE FIRST 256 BYTES OF GLOBAL RAM
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 12
      


                   ;  THEN ENTER THE COMMAND MODE.
                   ;
   C1D7   AF       STRTA:  XRA     A
   C1D8   4F               MOV     C,A
   C1D9   2104C8           LXI     H,DFLTS ;CLEAR AFTER USER PORT ADDRESSES
                   ;
   C1DC   77       CLERA:  MOV     M,A
   C1DD   23               INX     H
   C1DE   0C               INR     C
   C1DF   C2DCC1           JNZ     CLERA
                   ;
                   ; DETERMINE THE DEFAULT PORTS
                   ;     THIS COULD BECOME "MVI A,XX" FOR YOUR SPECIFIC PORTS
   C1E2   DBFF             IN      SENSE   ;GET SWITCHES
                   ;
   C1E4   47               MOV     B,A     ;SAVE IT
   C1E5   E603             ANI     3       ;MAKE IT A VALID PORT
   C1E7   3205C8           STA     DFLTS+1 ;SET DEFAULT OUTPUT PORT
   C1EA   B7               ORA     A       ;SEE IF THIS THE VDM
   C1EB   C2F4C1           JNZ     STRTB   ;NO--DO NOT RESET VDM
   C1EE   31FFCB           LXI     SP,SYSTP ;SET UP THE STACK FOR CALL
   C1F1   CDF9C0           CALL    PERSE   ;(REG A ASSUMED TO COME BACK ZERO)
   C1F4            STRTB   EQU     $       ;FINISH OFF THIS PORT THEN DO NEXT
   C1F4   210000           LXI     H,0     ;USE FOR CLEARING USER ADDRESSES
   C1F7   FE03             CPI     3       ;IS IT A USER PORT
   C1F9   CAFFC1           JZ      STRTC   ;YES-- DO NOT CLEAR IT
   C1FC   2202C8           SHLD    UOPRT   ;NO--CLEAR ADDR
   C1FF            STRTC   EQU     $       ;OUTPUT PORT ALL SET
   C1FF   78               MOV     A,B     ;FM SENSE SWITCHES
   C200   1F               RAR
   C201   1F               RAR             ;NEXT 2 BITS ARE INPUT PORT
   C202   E603             ANI     3       ;VALID PORT
   C204   3204C8           STA     DFLTS   ;THIS IS DEFAULT INPUT PORT
   C207   FE03             CPI     3       ;IS THIS ONE A USER PORT
   C209   CA0FC2           JZ      STRTD   ;YES--DO NOT CLEAR IT THEN
   C20C   2200C8           SHLD    UIPRT   ;NO--FORCE USER ADDRESS ZERO
   C20F            STRTD   EQU     $       ;1ST TIME INITIALIZATION ALL DONE NOW
   C20F   2A04C8           LHLD    DFLTS   ;PICK UP DEFAULT PORTS
   C212   2206C8           SHLD    IPORT   ;FORCE PORTS TO DEFAULT
   C215            COMN1   EQU     $       ;HERE TO TURN OFF TAPES, THEN COMMAND MODE
   C215   AF               XRA     A
   C216   D306             OUT     TAPPT   ;BE SURE TAPES ARE OFF
                   ;
                   ;
                   ;
                   ;            =--  COMMAND MODE  --=
                   ;
                   ;
                   ;   THIS ROUTINE GETS AND PROCESSES COMMANDS
                   ;
   C218   31FFCB   COMND:  LXI     SP,SYSTP ;SET STACK POINTER
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 13
      


   C21B   CD3AC3           CALL    PROMPT  ;PUT PROMPT ON SCREEN
   C21E   CD27C2           CALL    GCLI0   ;INIT TO GET COMMAND LINE
   C221   CD6AC2           CALL    COPRC   ;PROCESS THE LINE
   C224   C318C2           JMP     COMND   ;OVER AND OVER
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE READS A COMMAND LINE FROM THE SYSTEM
                   ;  KEYBOARD
                   ;
                   ;  C/R   TERMINATES THE SEQUENCE ERASING ALL CHARS TO THE
                   ;        RIGHT OF THE CURSOR
                   ;  L/F   TERMINATES THE SEQUENCE
                   ;  ESC   RESETS TO COMMAND MODE.
                   ;
   C227            GCLI0   EQU     $       ;HERE TO INIT FOR GCLIN
   C227   2163CA           LXI     H,INLIN-1 ;PT TO CHAR IN FRONT OF INPUT BFR
   C22A   3607             MVI     M,7     ;MAKE SURE IT IS "BELL" TO KEEP FM DEL'ING TOO FAR
   C22C   23               INX     H       ;NOW PT TO INPUT BFR
   C22D   220EC8           SHLD    INPTR   ;SAVE AS STARTING PTR
   C230   3E50             MVI     A,80    ;NUMBER OF CHARS IN LINE (MAX)
   C232            GCLI1   EQU     $       ;LOOP TO BLANK OUT LINE BFR
   C232   3620             MVI     M,' '   ;BLANKS
   C234   23               INX     H       ;NEXT CHAR
   C235   3D               DCR     A       ;FOR THIS COUNT
   C236   C232C2           JNZ     GCLI1   ;ENTIRE LINE
   C239   CD1FC0   GCLIN:  CALL    SINP    ;READ INPUT DEVICE
   C23C   CA39C2           JZ      GCLIN
   C23F   E67F             ANI     7FH     ;MAKE SURE NO X'80' BIT DURING CMND MODE
   C241   CA0FC2           JZ      STRTD   ;IF EITHER MODE (OR CTL-@)
   C244   47               MOV     B,A
   C245   FE0D             CPI     CR      ;IS IT CR?
   C247   CA18C1           JZ      CLIN2   ;YES--TERMINATE LINE HERE (CLR IF VDM)
   C24A   FE0A             CPI     LF      ;IS IT A LINEFEED
   C24C   C8               RZ              ;YES--TERMINATE LINE AS IS
   C24D   2A0EC8           LHLD    INPTR   ;CRNT LINE PTR
   C250   FE7F             CPI     7FH     ;DELETE CHR?
   C252   C25FC2           JNZ     GCLI2   ;NO--OK
   C255   0608             MVI     B,BACKS ;REPLACE IT
   C257   2B               DCX     H       ;BACK LINE PTR UP TOO
   C258   3E07             MVI     A,'G'-40H ;SEE IF A BELL
   C25A   BE               CMP     M       ;IS IT?
   C25B   C261C2           JNZ     GCLI3   ;NO--OK
   C25E   47               MOV     B,A     ;YES--RING THE BELL THEN
   C25F            GCLI2   EQU     $       ;STORE CHAR IN INPUT AREA
   C25F   70               MOV     M,B     ;PLACE CHAR INTO LINE
   C260   23               INX     H       ;NEXT CHAR
   C261            GCLI3   EQU     $       ;SAVE NEW LINE PTR
   C261   220EC8           SHLD    INPTR   ;SAVE PTR
                   ;
   C264   CD19C0   CONT:   CALL    SOUT
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 14
      


   C267   C339C2           JMP     GCLIN
                   ;
                   ;
                   ;
                   ;
                   ;      FIND AND PROCESS COMMAND
                   ;
   C26A            COPRC   EQU     $       ;PROCESS THIS COMMAND LINE
   C26A   CDAAC2           CALL    STUP    ;SETUP TO PROCESS INPUT LINE
   C26D   EB               XCHG            ;DE=ADDR
   C26E   2100C0           LXI     H,START ;PREP SO THAT HL WILL PT TO CUTER LATER
   C271   E5               PUSH    H       ;PLACE PTR TO CUTER ON STACK FOR LATER DISPT
   C272   CD6CC3           CALL    SCHR    ;SCAN PAST BLANKS
   C275   CA6BC4           JZ      ERR1    ;NO COMMAND?
   C278   EB               XCHG            ;HL HAS FIRST CHR
   C279   11BDC2           LXI     D,COMTAB ;POINT TO COMMAND TABLE
   C27C   CD91C2           CALL    FDCOM   ;SEE IF IN PRIMARY TABLE
   C27F   CC8EC2           CZ      FDCOU   ;TRY CUSTOM ONLY IF NOT PRIMARY COMMAND
   C282            DISP0   EQU     $       ;HERE TO EITHER DISPATCH OR DO ERROR
   C282   CA6CC4           JZ      ERR2    ;NOT IN EITHER TABLE
   C285   13               INX     D       ;PT DE TO ADDR OF RTN
   C286   EB               XCHG            ;HL=ADDR OF ADDR OF RTN
                   ; **** DROP THRU TO DISPT ***
                   ;
                   ; THIS ROUTINE DISPTACHES TO THE ADDR AT CONTENTS OF HL.
                   ; HL ARE RESTORED PRIOR TO GOING TO ROUTINE.
                   ;
   C287            DISPT   EQU     $       ;DISPATCH
   C287   7E               MOV     A,M     ;LOW BYTE
   C288   23               INX     H
   C289   66               MOV     H,M     ;HI BYTE
   C28A   6F               MOV     L,A     ;AND LO, HL NOW COMPLETE
   C28B            DISP1   EQU     $       ;HERE TO GO OFF TO HL DIRECTLY
   C28B   E3               XTHL            ;HL RESTORED AND ADDR ON STACK
   C28C   7D               MOV     A,L     ;ALWAYS PASS L IN "A" (PRIMARILY FOR SET'S)
   C28D   C9               RET             ;OFF TO ROUTINE
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE SEARCHES THROUGH A TABLE, POINTED TO
                   ;  BY 'DE', FOR A DOUBLE CHARACTER MATCH OF THE 'HL'
                   ;  MEMORY CONTENT.  IF NO MATCH IS FOUND THE SCAN ENDS
                   ;  WITH THE ZERO FLAG SET, ELSE NON-ZERO SET.
                   ;
   C28E            FDCOU   EQU     $       ;HERE TO SCAN CUSTOM TABLE
   C28E   113CC8           LXI     D,CUTAB ;PT TO CUSTOM RTN TBL
   C291   1A       FDCOM:  LDAX    D
   C292   B7               ORA     A       ;TEST FOR TABLE END
   C293   C8               RZ              ;NOT FOUND POST THAT AND RETURN
   C294   E5               PUSH    H       ;SAVE START OF SCAN ADDRESS
   C295   BE               CMP     M       ;TEST FIRST CHR
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 15
      


   C296   13               INX     D
   C297   C2A3C2           JNZ     NCOM
                   ;
   C29A   23               INX     H
   C29B   1A               LDAX    D
   C29C   BE               CMP     M       ;NOW SECOND CHARACTER
   C29D   C2A3C2           JNZ     NCOM    ;GOODNESS
                   ;
   C2A0   E1               POP     H       ;RETURN HL TO PT TO CHAR START
   C2A1   B7               ORA     A       ;FORCE TO NON-ZERO FLAG
   C2A2   C9               RET             ;LET CALLER KNOW
                   ;
                   ;
   C2A3   13       NCOM:   INX     D       ;GO TO NEXT ENTRY
   C2A4   13               INX     D
   C2A5   13               INX     D
   C2A6   E1               POP     H       ;GET BACK ORIGINAL ADDRESS
   C2A7   C391C2           JMP     FDCOM   ;CONTINUE SEARCH
                   ;
                   ;
                   ; SET UP TO PROCESS AN INPUT LINE
   C2AA            STUP    EQU     $       ;PREPARE WHETHER VDM OR NOT
   C2AA   2164CA           LXI     H,INLIN ;ASSUME NON-VDM INPUT
   C2AD   220EC8           SHLD    INPTR   ;ALSO RESET PTR FOR NOW
   C2B0   3A07C8           LDA     OPORT   ;SEE IF IT IS VDM
   C2B3   B7               ORA     A       ;IS IT THE VDM PORT
   C2B4   C0               RNZ             ;NO--HL ARE SET PROPERLY
   C2B5   CD5FC1           CALL    CREM    ;REMOVE CURSOR
   C2B8   0E01             MVI     C,1     ;GET VDM ADDR FM POSITION ONE
   C2BA   C349C1           JMP     VDAD2   ;GET SCRN ADDR
                   ;
                   ;           COMMAND TABLE
                   ;
                   ;  THIS TABLE DESCRIBES THE VALID COMMANDS FOR CUTER
                   ;
   C2BD            COMTAB  EQU     $       ;START OF KNOWN COMMANDS
   C2BD   4455             DB      'DU'    ;DUMP
   C2BF   ADC3             DW      DUMP
   C2C1   454E             DB      'EN'    ;ENTR
   C2C3   14C4             DW      ENTER
   C2C5   4558             DB      'EX'    ;EXEC
   C2C7   49C4             DW      EXEC
   C2C9   4745             DB      'GE'    ;GET
   C2CB   A1C4             DW      TLOAD
   C2CD   5341             DB      'SA'    ;SAVE
   C2CF   E0C4             DW      TSAVE
   C2D1   5845             DB      'XE'    ;XEQ
   C2D3   A0C4             DW      TXEQ
   C2D5   4341             DB      'CA'    ;CAT
   C2D7   27C5             DW      TLIST
   C2D9   5345             DB      'SE'    ;SET COMMAND
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 16
      


   C2DB   76C5             DW      CSET
   C2DD   4355             DB      'CU'    ;CUSTOM COMMAND ENTER/CLEAR
   C2DF   B9C5             DW      CUSET
   C2E1   00               DB      0       ;END OF TABLE MARK
                   ;
                   ;
                   ;               DISPLAY DRIVER COMMAND TABLE
                   ;
                   ;     THIS TABLE DEFINES THE CHARACTERS FOR SPECIAL
                   ;  PROCESSING. IF THE CHARACTER IS NOT IN THE TABLE IT
                   ;  GOES TO THE SCREEN.
                   ;
   C2E2   0B       TBL:    DB      CLEAR   ;SCREEN
   C2E3   F9C0             DW      PERSE
   C2E5   17               DB      UP      ;CURSOR
   C2E6   2DC1             DW      PUP
   C2E8   1A               DB      DOWN    ;"
   C2E9   EFC0             DW      PDOWN
   C2EB   01               DB      LEFT    ;"
   C2EC   34C1             DW      PLEFT
   C2EE   13               DB      RIGHT   ;"
   C2EF   3EC1             DW      PRIT
   C2F1   0E               DB      HOME    ;"
   C2F2   09C1             DW      PHOME
   C2F4   0D               DB      CR      ;CARRIAGE RETURN
   C2F5   70C1             DW      PCR
   C2F7   0A               DB      LF      ;LINE FEED
   C2F8   75C1             DW      PLF
   C2FA   08               DB      BACKS   ;BACK SPACE
   C2FB   67C1             DW      PBACK
   C2FD   1B               DB      ESC     ;ESCAPE KEY
   C2FE   81C1             DW      PESC
   C300   00               DB      0       ;END OF TABLE
                   ;
                   ;   OUTPUT DEVICE TABLE
                   ;
   C301   78C0     OTAB:   DW      VDM01   ;VDM DRIVER
   C303   47C0             DW      SEROT   ;SERIAL OUTPUT
   C305   5AC0             DW      PAROT   ;PARALLEL OUTPUT
   C307   6CC0             DW      ERROT   ;ERROR OR USER DRIVER HANDLER
                   ;
                   ;    INPUT DEVICE TABLE
                   ;
   C309   35C0     ITAB:   DW      KREA1   ;KEYBOARD INPUT
   C30B   3EC0             DW      SREA1   ;SERIAL INPUT
   C30D   52C0             DW      PARIT   ;PARALLEL INPUT
   C30F   65C0             DW      ERRIT   ;ERROR OR USER DRIVER HANDLER
                   ;
                   ;
                   ;       SECONDARY COMMAND TABLE FOR SET COMMAND
                   ;
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 17
      


   C311   5441     SETAB:  DB      'TA'    ;SET TAPE SPEED
   C313   8AC5             DW      TASPD
   C315   533D             DB      'S='    ;SET DISPLAY SPEED
   C317   95C5             DW      DISPD
   C319   493D             DB      'I='    ;SET INPUT PORT
   C31B   99C5             DW      SETIN
   C31D   4F3D             DB      'O='    ;SET OUTPUT PORT
   C31F   9DC5             DW      SETOT
   C321   4349             DB      'CI'    ;SET CUSTOM DRIVER ADDRESS
   C323   A1C5             DW      SETCI
   C325   434F             DB      'CO'    ;SET CUSTOM OUTPUT DRIVER ADDRESS
   C327   A5C5             DW      SETCO
   C329   5845             DB      'XE'    ;SET HEADER XEQ ADDRESS
   C32B   ADC5             DW      SETXQ
   C32D   5459             DB      'TY'    ;SET HEADER TYPE
   C32F   A9C5             DW      SETTY
   C331   4E3D             DB      'N='    ;SET NUMBER OF NULLS
   C333   B1C5             DW      SETNU
   C335   4352             DB      'CR'    ;SET CRC (NORMAL OR IGNORE CRC ERRORS)
   C337   B5C5             DW      SETCR
   C339   00               DB      0       ;END OF TABLE MARK
                   ; -*-
                   ;
                   ;
                   ;      OUTPUT A CRLF FOLLOWED BY A PROMPT
                   ;
   C33A   CD42C3   PROMPT: CALL    CRLF
   C33D   063E             MVI     B,'>'   ;THE PROMPT
   C33F   C319C0           JMP     SOUT    ;PUT IT ON THE SCREEN
                   ;
   C342   060A     CRLF:   MVI     B,LF    ;LINE FEED
   C344   CD19C0           CALL    SOUT
   C347   060D             MVI     B,CR    ;CARRIAGE RETURN
   C349   CD19C0           CALL    SOUT
   C34C   3A10C8           LDA     NUCNT   ;GET COUNT OF NULLS TO OUTPUT
   C34F   4F               MOV     C,A     ;SAVE COUNT IN C
   C350   0D       NULOT:  DCR     C
   C351   F8               RM              ;COUNTED DOWN PAST ZERO (MAX COUNT IS X'7F')
   C352   AF               XRA     A       ;HERE IS THE NULL
   C353   CD10C4           CALL    OUTH    ;OUTPUT IT
   C356   C350C3           JMP     NULOT   ;LOOP FOR NUMBER OF NULLS
                   ;
                   ;
                   ;  SCAN OVER UP TO 12 CHARACTERS LOOKING FOR A BLANK
                   ;
   C359   0E0C     SBLK:   MVI     C,12    ;MAXIMUM COMMAND STRING
   C35B   1A       SBLK1:  LDAX    D
   C35C   FE20             CPI     BLANK
   C35E   CA6CC3           JZ      SCHR    ;GOT A BLANK NOW SCAN PAST IT
   C361   13               INX     D
   C362   FE3D             CPI     '='     ;A EQUAL WILL ALSO STOP US (AT NEXT CHAR)
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 18
      


   C364   CA6CC3           JZ      SCHR    ;FOUND, DE PT TO NEXT CHAR
   C367   0D               DCR     C       ;NO MORE THAN TWELVE
   C368   C25BC3           JNZ     SBLK1
   C36B   C9               RET             ;GO BACK WITH ZERO FLAG SET
                   ;
                   ;
                   ;  SCAN PAST UP TO 10 BLANK POSITIONS LOOKING FOR
                   ; A NON BLANK CHARACTER.
                   ;
   C36C   0E0A     SCHR:   MVI     C,10    ;SCAN TO FIRST NON BLANK CHR WITHIN 10
   C36E   1A       SCHR1:  LDAX    D       ;GET NEXT CHARACTER
   C36F   FE20             CPI     SPACE
   C371   C0               RNZ             ;WE'RE PAST THEM
   C372   13               INX     D       ;NEXT SCAN ADDRESS
   C373   0D               DCR     C
   C374   C8               RZ              ;COMMAND ERROR
   C375   C36EC3           JMP     SCHR1   ;KEEP LOOPING
                   ;
                   ;  THIS ROUTINE SCANS OVER CHARACTERS, PAST BLANKS AND
                   ; CONVERTS THE FOLLOWING ADDRESS TO HEX.  ERRORS RETURN TO
                   ; THE ERROR HANDLER.
                   ;
   C378   CD59C3   SCONV:  CALL    SBLK
   C37B   CA6BC4           JZ      ERR1
                   ;
                   ;  THIS ROUTINE CONVERTS ASCII DIGITS INTO BINARY FOLLOWING
                   ; A STANDARD HEX CONVERSION.  THE SCAN STOPS WHEN AN ASCII
                   ; SPACE IS ENCOUNTERED.  PARAMETER ERRORS REPLACE THE ERROR
                   ; CHARACTER ON THE SCREEN WITH A QUESTION MARK.
                   ;
   C37E   210000   SHEX:   LXI     H,0     ;CLEAR H & L
   C381   1A       SHE1:   LDAX    D       ;GET CHARACTER
   C382   FE20             CPI     20H     ;IS IT A SPACE?
   C384   C8               RZ              ;IF SO
   C385   FE2F             CPI     '/'
   C387   C8               RZ
   C388   FE3A             CPI     ':'
   C38A   C8               RZ
                   ;
   C38B   29       HCONV:  DAD     H       ;MAKE ROOM FOR THE NEW ONE
   C38C   29               DAD     H
   C38D   29               DAD     H
   C38E   29               DAD     H
   C38F   CD9BC3           CALL    HCOV1   ;DO THE CONVERSION
   C392   D26BC4           JNC     ERR1    ;NOT VALID HEXIDECIMAL VALUE
   C395   85               ADD     L
   C396   6F               MOV     L,A     ;MOVE IT IN
   C397   13               INX     D       ;BUMP THE POINTER
   C398   C381C3           JMP     SHE1
                   ;
   C39B   D630     HCOV1:  SUI     48      ;REMOVE ASCII BIAS
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 19
      


   C39D   FE0A             CPI     10
   C39F   D8               RC              ;IF LESS THAN 9
   C3A0   D607             SUI     7       ;IT'S A LETTER??
   C3A2   FE10             CPI     10H
   C3A4   C9               RET             ;WITH TEST IN HAND
                   ;
                   ;
                   ;  THIS ROUTINE WILL SEE IF A FIELD (OPERAND) IS PRESENT.
                   ;  IF NOT, THEN HL WILL REMAIN AS THEY WERE ON ENTRY.
                   ;  IF IT WAS PRESENT, THEN HL=THAT VALUE IN HEX.
                   ;
   C3A5            PSCAN   EQU     $       ;OPTIONAL FIELD SCANNER
   C3A5   CD59C3           CALL    SBLK    ;SEE IF FIELD IS PRESENT
   C3A8   C8               RZ              ;RETURN LEAVING HL AS THEY WERE ON ENTRY
   C3A9   CD7EC3           CALL    SHEX    ;FIELD IS THERE, GO GET IT
   C3AC   C9               RET             ;HL= EITHER OPTIONAL FIELD (HEX), OR AS IT WAS
                   ;
                   ;
                   ;
                   ;
                   ;           DUMP COMMAND
                   ;
                   ;     THIS ROUTINE DUMPS CHARACTERS FROM MEMORY TO THE
                   ;  CURRENT OUTPUT DEVICE.
                   ;  ALL VALUES ARE DESPLAYED AS ASCII HEX.
                   ;
                   ;  THE COMMAND FORM IS AS FOLLOWS:
                   ;
                   ;        DUMP  ADDR1  ADDR2
                   ;
                   ;    THE VALUES FROM ADDR1 TO ADDR2 ARE THEN OUTPUT TO THE
                   ;  OUTPUT DEVICE.  IF ONLY ADDR1 IS SPECIFIED THEN THE
                   ;  VALUE AT THAT ADDRESS IS OUTPUT.
                   ;
                   ;  IF WHILE DUMPING, THE MODE KEY IS PRESSED, THE DUMP WILL
                   ;  BE TERMINATED.  IF THE SPACE BAR IS PRESSED, THE DUMP
                   ;  WILL BE TEMPORARILY SUSPENDED UNTIL ANY KEY IS PRESSED.
                   ;
   C3AD            DUMP    EQU     $       ;SET UP REGS TO DUMP SPECIFIED AREA
   C3AD   CD78C3           CALL    SCONV   ;GET START ADDR (REQUIRED)
   C3B0   E5               PUSH    H       ;SAVE THE START ADDR
   C3B1   CDA5C3           CALL    PSCAN   ;GET OPTIONAL END ADDR, HL=THIS OR START ADDR
   C3B4   D1               POP     D       ;DE=START ADDR
   C3B5   EB               XCHG            ;DE=END ADDR, HL=START ADDR NOW
                   ;
   C3B6   CD42C3   DLOOP:  CALL    CRLF
   C3B9   CDD9C3           CALL    ADOUT   ;OUTPUT ADDRESS
   C3BC   CDF7C3           CALL    BOUT    ;ANOTHER SPACE TO KEEP IT PRETTY
   C3BF   0E10             MVI     C,16    ;VALUES PER LINE
                   ;
   C3C1   7E       DLP1:   MOV     A,M     ;GET THE CHR
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 20
      


   C3C2   C5               PUSH    B       ;SAVE VALUE COUNT
   C3C3   CDDEC3           CALL    HBOUT   ;SEND IT OUT WITH A BLANK
   C3C6   7C               MOV     A,H     ;CRNT ADDR
   C3C7   BA               CMP     D       ;VERSUS ENDING ADDR
   C3C8   DAD0C3           JC      DLP1A   ;NOT DONE YET
   C3CB   7D               MOV     A,L     ;TRY LOW ORDER BYTE
   C3CC   BB               CMP     E
   C3CD   D218C2           JNC     COMND   ;ALL DONE WHEN CRNT REACHES ENDING
   C3D0            DLP1A   EQU     $       ;HERE TO KEEP DUMPING
   C3D0   C1               POP     B       ;VALUES PER LINE
   C3D1   23               INX     H
   C3D2   0D               DCR     C       ;BUMP THE LINE COUNT
   C3D3   C2C1C3           JNZ     DLP1    ;NOT ZERO IF MORE FOR THIS LINE
   C3D6   C3B6C3           JMP     DLOOP   ;DO A LFCR BEFORE THE NEXT
                   ;
                   ;    OUTPUT HL AS HEX 16 BIT VALUE
                   ;
   C3D9   7C       ADOUT:  MOV     A,H     ;H FIRST
   C3DA   CDFCC3           CALL    HEOUT
   C3DD   7D               MOV     A,L     ;THEN L FOLLOWED BY A SPACE
                   ;
   C3DE   CDFCC3   HBOUT:  CALL    HEOUT
   C3E1   CD1FC0           CALL    SINP    ;SEE IF WE SHD ESCAPE FM DUMP
   C3E4   CAF7C3           JZ      BOUT    ;NO--ADD THE SPACE THEN
   C3E7   E67F             ANI     7FH     ;MAKE SURE ITS CLEAR OF PARITY
   C3E9   CA18C2           JZ      COMND   ;EITHER MODE (OR CTL-@)
   C3EC   FE20             CPI     ' '     ;IS IT SPACE
   C3EE   C2F7C3           JNZ     BOUT    ;NO--IGNORE THE CHAR
   C3F1   CD1FC0   WTLP1:  CALL    SINP    ;ON SPACE, WAIT FOR ANY OTHER CHAR
   C3F4   CAF1C3           JZ      WTLP1   ;JUST LOOP AFTER A SPACE UNTIL ANY KEY PRESSED
   C3F7   0620     BOUT:   MVI     B,' '
   C3F9   C319C0           JMP     SOUT    ;PUT IT OUT
                   ;
   C3FC   4F       HEOUT:  MOV     C,A     ;GET THE CHARACTER
   C3FD   0F               RRC
   C3FE   0F               RRC             ;MOVE THE HIGH FOUR DOWN
   C3FF   0F               RRC
   C400   0F               RRC
   C401   CD05C4           CALL    HEOU1   ;PUT THEM OUT
   C404   79               MOV     A,C     ;THIS TIME THE LOW FOUR
                   ;
   C405   E60F     HEOU1:  ANI     0FH     ;FOUR ON THE FLOOR
   C407   C630             ADI     48      ;WE WORK WITH ASCII HERE
   C409   FE3A             CPI     58      ;0-9?
   C40B   DA10C4           JC      OUTH    ;YUP!
   C40E   C607             ADI     7       ;MAKE IT A LETTER
   C410   47       OUTH:   MOV     B,A     ;OUTPUT IT FROM REGISTER 'B'
   C411   C319C0           JMP     SOUT
                   ;
                   ;
                   ;           ENTR COMMAND
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 21
      


                   ;
                   ;   THIS ROUTINE GETS VALUES FROM THE KEYBOARD AND ENTERS
                   ; THEM INTO MEMORY.  THE INPUT VALUES ARE SCANNED FOLLOWING
                   ; A STANDARD 'GCLIN' INPUT SO ON-SCREEN EDITING MAY TAKE
                   ; PLACE PRIOR TO THE LINE TERMINATOR.  A SLASH '/'
                   ; ENDS THE ROUTINE AND RETURNS CONTROL TO THE COMMAND MODE.
                   ;
   C414   CD78C3   ENTER:  CALL    SCONV   ;SCAN OVER CHARS AND GET ADDRESS
   C417   E5               PUSH    H       ;SAVE ADDRESS
                   ;
   C418   CD42C3   ENLOP:  CALL    CRLF
   C41B   063A             MVI     B,':'
   C41D   CD19C0           CALL    SOUT    ;DSPLY THE COLON
   C420   CD27C2           CALL    GCLI0   ;INIT AND PROCESS A LINE
   C423   CDAAC2           CALL    STUP    ;SET UP TO PROCESS INPUT LINE
   C426   EB               XCHG            ;....TO DE
                   ;
                   ;
   C427   0E03     ENLO1:  MVI     C,3     ;NO MORE THAN THREE SPACES BETWEEN VALUES
   C429   CD6EC3           CALL    SCHR1   ;SCAN TO NEXT VALUE
   C42C   CA18C4           JZ      ENLOP   ;LAST ENTRY FOUND START NEW LINE
                   ;
   C42F   FE2F             CPI     '/'     ;COMMAND TERMINATOR?
   C431   CA18C2           JZ      COMND   ;IF SO...
   C434   CD7EC3           CALL    SHEX    ;CONVERT VALUE
   C437   FE3A             CPI     ':'     ;ADDRESS TERMINATOR?
   C439   CA44C4           JZ      ENLO3   ;GO PROCESS IF SO
   C43C   7D               MOV     A,L     ;GET LOW PART AS CONVERTED
   C43D   E1               POP     H       ;GET MEMORY ADDRESS
   C43E   77               MOV     M,A     ;PUT IN THE VALUE
   C43F   23               INX     H
   C440   E5               PUSH    H       ;BACK GOES THE ADDRESS
   C441   C327C4           JMP     ENLO1   ;CONTINUE THE SCAN
                   ;
   C444   E3       ENLO3:  XTHL            ;PUT NEW ADDRESS ON STACK
   C445   13               INX     D       ;MOVE SCAN PAST TERMINATOR
   C446   C327C4           JMP     ENLO1
                   ;
                   ;
                   ;              EXECUTE COMMAND
                   ;
                   ;   THIS ROUTINE GETS THE FOLLOWING PARAMETER AND DOES A
                   ; PROGRAM JUMP TO THE LOCATION GIVEN BY IT.  IF PROPER
                   ; STACK OPERATIONS ARE USED WITHIN THE EXTERNAL PROGRAM
                   ; IT CAN DO A STANDARD 'RET'URN TO THE CUTER COMMAND MODE.
                   ;
                   ;
   C449   CD78C3   EXEC:   CALL    SCONV   ;SCAN PAST BLANKS AND GET PARAMETER
   C44C            EXEC1   EQU     $       ;HERE TO GO TO HL
   C44C   E5               PUSH    H       ;SAVE ON STACK
   C44D   2100C0           LXI     H,START ;LET USER KNOW WHERE WE ARE
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 22
      


   C450   C9               RET             ;AND OFF TO USER
                   ;
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE GETS A NAME OF UP TO 5 CHARACTERS
                   ;  FROM THE INPUT STRING.  IF THE TERMINATOR IS A
                   ;  SLASH (/) THEN THE CHARACTER FOLLOWING IS TAKEN
                   ;  AS THE CASSETTE UNIT SPECIFICATION.
                   ;
                   ;
   C451            NAME0   EQU     $       ;ENTER HERE TO SET HL TO THEAD
   C451   211CC8           LXI     H,THEAD ;PT WHERE TO PUT NAME
   C454   CD59C3   NAME:   CALL    SBLK    ;SCAN OVER TO FIRST CHRS
   C457   0606             MVI     B,6
                   ;
   C459   1A       NAME1:  LDAX    D       ;GET CHARACTER
   C45A   FE20             CPI     ' '     ;NO UNIT DELIMITER
   C45C   CA80C4           JZ      NFIL
   C45F   FE2F             CPI     '/'     ;UNIT DELIMITER
   C461   CA80C4           JZ      NFIL
   C464   77               MOV     M,A
   C465   13               INX     D       ;BUMP THE SCAN POINTER
   C466   23               INX     H
   C467   05               DCR     B
   C468   C259C4           JNZ     NAME1   ;NAME IS OK, FALL THRU TO 'ERR1' IF NOT
                   ;
                   ;     CUTER ERROR HANDLER
                   ;
   C46B   EB       ERR1:   XCHG            ;GET SCAN ADDRESS
   C46C   363F     ERR2:   MVI     M,'?'   ;FLAG THE ERROR
   C46E   3A07C8           LDA     OPORT   ;SEE IF VIA VDM DRIVER
   C471   B7               ORA     A
   C472   CA18C2           JZ      COMND   ;YES--VDM SCREEN NOW HAS THE ?
   C475   CD42C3           CALL    CRLF
   C478   063F             MVI     B,'?'   ;SET UP THE ????
   C47A   CD19C0           CALL    SOUT    ;INDICATE INPUT NOT VALID
   C47D   C318C2           JMP     COMND   ;NOW READY FOR NEXT INPUT
                   ;
                   ;
                   ;
                   ;  HERE WE HAVE SCANNED OFF THE NAME. ZERO FILL IN FOR
                   ;  NAMES LESS THAN FIVE CHARACTERS.
                   ;
   C480   3600     NFIL:   MVI     M,0     ;PUT IN AT LEAST ONE ZERO
   C482   23               INX     H
   C483   05               DCR     B
   C484   C280C4           JNZ     NFIL    ;LOOP UNTIL B IS ZERO
                   ;
   C487   FE2F             CPI     '/'     ;IS THERE A UNIT SPECIFICATION?
   C489   3E01             MVI     A,1     ;PRETEND NOT
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 23
      


   C48B   C294C4           JNZ     DEFLT
   C48E   13               INX     D       ;MOVE PAST THE TERMINATOR
   C48F   CD6CC3           CALL    SCHR    ;GO GET IT
   C492   D630             SUI     '0'     ;REMOVE ASCII BIAS
                   ;
   C494            DEFLT   EQU     $       ;CNVRT TO INTERNAL BIT FOR TAPE CONTROL
   C494   E601             ANI     1       ;JUST BIT ZERO
   C496   3E80             MVI     A,TAPE1 ;ASSUME TAPE ONE
   C498   C29CC4           JNZ     STUNT   ;IF NON ZERO, IT IS ONE
   C49B   1F               RAR             ;ELSE MAKE IT TAPE TWO
   C49C   3254C8   STUNT:  STA     FNUMF   ;SET IT IN
   C49F   C9               RET
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE PROCESSES THE XEQ AND GET COMMANDS
                   ;
                   ;
   C4A0   3E       TXEQ:   DB      3EH     ;THIS BEGINS "MVI" OF THE "XRA" FOLLOWING
   C4A1   AF       TLOAD:  XRA     A       ;A=0 TLOAD, A=AF (#0) THEN XEQ
   C4A2   F5               PUSH    PSW     ;SAVE FLAG TO SAY WHETHER LOAD OR XEQ
   C4A3   212CC8           LXI     H,DHEAD ;PLACE DUMMY HDR HERE FOR COMPARES
   C4A6   CD54C4           CALL    NAME    ;SET IN NAME AND UNIT
   C4A9   210000           LXI     H,0     ;ASSUME LOAD ADDR NOT GIVEN
   C4AC   CDA5C3           CALL    PSCAN   ;HL EITHER =0, OR OVERRIDE LOAD ADDR
                   ;
   C4AF   EB       TLOA2:  XCHG            ;PUT ADDRESS IN DE
   C4B0   212CC8           LXI     H,DHEAD ;PT TO NORMAL HDR
   C4B3   7E               MOV     A,M     ;GET 1ST CHAR OF NAME
   C4B4   B7               ORA     A       ;IS THERE A NAME?
   C4B5   C2BBC4           JNZ     TLOA3   ;YES--LOOK FOR IT
   C4B8   211CC8           LXI     H,THEAD ;PT TO SAME HDR TO LOAD NEXT FILE
   C4BB   E5       TLOA3:  PUSH    H       ;SAVE PTR TO WHICH HDR TO USE
   C4BC   CD44C5           CALL    ALOAD   ;GET UNIT AND SPEED
   C4BF   E1               POP     H       ;RESTORE PTR TO PROPER HDR TO USE
   C4C0   CDC7C6           CALL    RTAPE   ;READ IN THE TAPE
   C4C3   DA10C5           JC      TAERR   ;TAPE ERROR?
                   ;
   C4C6   CD4CC5           CALL    NAOUT   ;PUT OUT THE HEADER PARAMETERS
   C4C9   F1               POP     PSW     ;RESTORE FLAG SAYING WHETHER IT WAS LOAD OR XEQ
   C4CA   B7               ORA     A
   C4CB   C8               RZ              ;AUTO XEQ NOT WANTED
   C4CC   3A22C8           LDA     HTYPE   ;CHECK TYPE
   C4CF   B7               ORA     A       ;SET FLAGS
   C4D0   FA10C5           JM      TAERR   ;TYPE IS NON XEQ
   C4D3   3A21C8           LDA     THEAD+5
   C4D6   B7               ORA     A
   C4D7   C210C5           JNZ     TAERR   ;THE BYTE MUST BE ZERO FOR AUTO XEQ
   C4DA   2A27C8           LHLD    XEQAD   ;GET THE TAPE ADDRESS
   C4DD   C34CC4           JMP     EXEC1   ;AND GO OFF TO IT
                   ;
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 24
      


                   ;
                   ;
                   ;   THIS ROUTINE IS USED TO SAVE PROGRAMS AND DATA ON
                   ;   THE CASSETTE UNIT.
                   ;
                   ;
   C4E0            TSAVE   EQU     $       ;SAVE MEMORY IMAGE TO TAPE
   C4E0   CD51C4           CALL    NAME0   ;GET NAME AND UNIT
   C4E3   CD78C3           CALL    SCONV   ;GET START ADDRESS
   C4E6   E5               PUSH    H       ;SAVE START ADDR FOR SIZE COMPUTATION LATER
   C4E7   CD78C3           CALL    SCONV   ;GET END ADDR (REQUIRED)
   C4EA   E3               XTHL            ;HL=START ADDR NOW, STACK=END ADDR
   C4EB   E5               PUSH    H       ;STACK =START FOLLOWED BY END
   C4EC   CDA5C3           CALL    PSCAN   ;SEE IF RETRIEVE FROM ADDR
   C4EF   2225C8           SHLD    LOADR   ;EITHER ACTUAL START, OR OVERRIDE INTO HDR
   C4F2   E1               POP     H       ;HL=START ADDR
   C4F3   D1               POP     D       ;DE=END ADDR
   C4F4   E5               PUSH    H       ;PUT START BACK ONTO STACK
   C4F5   7B               MOV     A,E     ;SIZE=END-START+1
   C4F6   95               SUB     L
   C4F7   6F               MOV     L,A
   C4F8   7A               MOV     A,D
   C4F9   DE00             SBI     0       ;THIS EQUALS A "SBB H"
   C4FB   94               SUB     H       ;THIS IS NEEDED
   C4FC   67               MOV     H,A
   C4FD   23               INX     H
   C4FE   2223C8           SHLD    BLOCK   ;STORE THE SIZE
   C501   E5               PUSH    H       ;SAVE AS THE BLOCK SIZE
                   ;
   C502   CD44C5           CALL    ALOAD   ;GET UNIT AND SPEED
   C505   211CC8           LXI     H,THEAD ;PT TO HEADER TO WRITE
   C508   CDADC7           CALL    WHEAD   ;TURN TAPE ON, THEN WRITE HEADER
   C50B   D1               POP     D       ;GET BACK THE SIZE
   C50C   E1               POP     H       ;AND GET BACK THE ACTUAL START ADDR
   C50D   C38DC7           JMP     WTAP1   ;WRITE THE BLK (W/EXTRA PUSH)
                   ;
                   ;   OUTPUT ERROR AND HEADER
                   ;
   C510   CD42C3   TAERR:  CALL    CRLF
   C513   1606             MVI     D,6
   C515   2121C5           LXI     H,ERRM
   C518   CD66C5           CALL    NLOOP   ;OUTPUT ERROR
   C51B   CD4CC5           CALL    NAOUT   ;THEN THE HEADER
   C51E   C315C2           JMP     COMN1
                   ;
   C521   4552524F ERRM:   DB      'ERROR '
   C525   5220    
                    
                   ;
                   ;
                   ;              CAT COMMAND
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 25
      


                   ;
                   ;   THIS ROUTINE READS HEADERS FROM THE TAPE AND OUTPUTS
                   ;   THEM TO THE OUTPUT DEVICE.  IT CONTINUES UNTIL THE
                   ;   MODE KEY IS DEPRESSED.
                   ;
   C527            TLIST   EQU     $       ;PRODUCE A LIST OF FILES ON A TAPE
   C527   CD51C4           CALL    NAME0   ;GET UNIT IF ANY (NAME IS IGNORED)
   C52A   CD42C3           CALL    CRLF    ;START ON A FRESH LINE
                   ;
                   ;
   C52D   CD44C5   LLIST:  CALL    ALOAD
   C530   0601             MVI     B,1
   C532   CDEDC7           CALL    TON     ;TURN ON THE TAPE
   C535   CD1FC7   LIST1:  CALL    RHEAD
   C538   DA15C2           JC      COMN1   ;TRUN OFF THE TAPE UNIT
   C53B   C235C5           JNZ     LIST1
   C53E   CD4CC5           CALL    NAOUT   ;OUTPUT THE HEADER
   C541   C32DC5           JMP     LLIST
                   ;
                   ;
                   ;   THIS ROUTINE GETS THE CASSETTE UNIT NUMBER AND
                   ;   SPEED TO REGISTER "A" FOR THE TAPE CALLS
                   ;
   C544   2154C8   ALOAD:  LXI     H,FNUMF ;POINT TO THE UNIT SPECIFICATION
   C547   3A0DC8           LDA     TSPD    ;GET THE TAPE SPEED
   C54A   B6               ORA     M       ;PUT THEM TOGETHER
   C54B   C9               RET             ;AND GO BACK
                   ;
                   ;   THIS ROUTINE OUTPUTS THE NAME AND PARAMETERS OF
                   ;   THEAD TO THE OUTPUT DEVICE.
                   ;
                   ;
   C54C   1608     NAOUT:  MVI     D,8
   C54E   211BC8           LXI     H,THEAD-1 ;POINT TO THE HEADER
   C551   CD66C5           CALL    NLOOP   ;OUTPUT THE HEADER
   C554   CDF7C3           CALL    BOUT    ;ANOTHER BLANK
   C557   2A25C8           LHLD    LOADR   ;NOW THE LOAD ADDRESS
   C55A   CDD9C3           CALL    ADOUT   ;PUT IT OUT
   C55D   2A23C8           LHLD    BLOCK   ;AND THE BLOCK SIZE
   C560   CDD9C3           CALL    ADOUT
   C563   C342C3           JMP     CRLF    ;DO THE CRLF AND RETURN
                   ;
                   ;
   C566   7E       NLOOP:  MOV     A,M     ;GET CHARACTER
   C567   B7               ORA     A
   C568   C26DC5           JNZ     CHRLI   ;IF IT ISN'T A ZERO
   C56B   3E20             MVI     A,' '   ;SPACE OTHERWISE
   C56D            CHRLI   EQU     $       ;CHAR IS OK TO SEND
   C56D   CD10C4           CALL    OUTH    ;OUTPUT IT FROM A REG
   C570   23               INX     H
   C571   15               DCR     D
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 26
      


   C572   C266C5           JNZ     NLOOP
   C575   C9               RET
                   ;
                   ;
                   ;
                   ;
                   ;      "SET" COMMAND
                   ;
                   ;   THIS ROUTINE GETS THE ASSOCIATED PARAMETER AND
                   ;   DISPATCHES TO THE PROPER ROUTINE FOR SETTING
                   ;   MEMORY VALUES.
                   ;
   C576   CD59C3   CSET:   CALL    SBLK    ;SCAN TO SECONDARY COMMAND
   C579   CA6BC4           JZ      ERR1    ;MUST HAVE AT LEAST SOMETHING!!
   C57C   D5               PUSH    D       ;SAVE SCAN ADDRESS
   C57D   CD78C3           CALL    SCONV   ;CONVERT FOLLOWING VALUE
   C580   E3               XTHL            ;HL=SAVED SCAN ADDR AND STACK=VALUE
   C581   1111C3           LXI     D,SETAB ;SECONDARY COMMAND TABLE
   C584   CD91C2           CALL    FDCOM   ;TRY TO LOCATE IT
   C587   C382C2           JMP     DISP0   ;OFF TO IT OR ERROR IF NOT IN TBL
                   ;
                   ;
                   ;  THIS ROUTINE SETS THE TAPE SPEED
                   ;
   C58A            TASPD   EQU     $       ;GET CONVERTED VALUE
   C58A   B7               ORA     A       ;IS IT ZERO?
   C58B   CA90C5           JZ      SETSP   ;YES--THAT IS A PROPER SPEED
   C58E   3E20             MVI     A,32    ;NO--SET SPEED PROPERLY THEN
   C590   320DC8   SETSP:  STA     TSPD
   C593   C9               RET
                   ;
                   ;
   C594            STSPD   EQU     $       ;VDM ESCAPE SEQUENCE COMES HERE
   C594   78               MOV     A,B     ;GET CHAR FOR FOLLOWING DISPD
   C595            DISPD   EQU     $       ;SET DISPLAY SPEED
   C595   320BC8           STA     SPEED
   C598   C9               RET
                   ;
                   ;
   C599            SETIN   EQU     $       ;SET AN INPUT PSUEDO PORT
   C599   3206C8           STA     IPORT
   C59C   C9               RET
                   ;
                   ;
   C59D            SETOT   EQU     $       ;SET AN OUTPUT PSUEDO PORT
   C59D   3207C8           STA     OPORT
   C5A0   C9               RET
                   ;
                   ;
   C5A1            SETCI   EQU     $       ;DEFINE USER INPUT RTN ADDR
   C5A1   2200C8           SHLD    UIPRT
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 27
      


   C5A4   C9               RET
                   ;
                   ;
   C5A5            SETCO   EQU     $       ;DEFINE USER OUTPUT RTN ADDR
   C5A5   2202C8           SHLD    UOPRT
   C5A8   C9               RET
                   ;
                   ;
   C5A9            SETTY   EQU     $       ;SET TAPE HDR TYPE
   C5A9   3222C8           STA     HTYPE
   C5AC   C9               RET
                   ;
                   ;
   C5AD            SETXQ   EQU     $       ;SET TAPE-EXECUTE ADDDR FOR HDR
   C5AD   2227C8           SHLD    XEQAD
   C5B0   C9               RET
                   ;
                   ;
   C5B1            SETNU   EQU     $       ;HERE TO SET NUMBER OF NULLS
   C5B1   3210C8           STA     NUCNT   ;THIS IS IT
   C5B4   C9               RET
                   ;
                   ;
   C5B5            SETCR   EQU     $       ;SET CRC TO BE NORMAL, OR IGNORE CRC ERRORS
   C5B5   3211C8           STA     IGNCR   ;FF=IGNORE CRC ERRORS, ELSE=NORMAL
   C5B8   C9               RET
                   ;
                   ;
   C5B9            CUSET   EQU     $       ;TRY TO SET/CLEAR CUSTOM ROUTINE ADDR
   C5B9   CD51C4           CALL    NAME0   ;GET A NAME (S/B 2 CHARS OR MORE)
   C5BC   2118C2           LXI     H,COMND ;PT HERE IN CASE ADDR NOT GIVEN
   C5BF   CDA5C3           CALL    PSCAN   ;GET OPTIONAL OPERAND IF ANY
   C5C2   E5               PUSH    H       ;SAVE THAT VALUE (IF ANY)
   C5C3   211CC8           LXI     H,THEAD ;PT TO NAME
   C5C6   CD8EC2           CALL    FDCOU   ;SEE IF NAME IS KNOWN IN CUST TABLE
   C5C9   CACFC5           JZ      CUSE2   ;NO--PROCEED TO KNOW IT
   C5CC   1B               DCX     D       ;DE PT TO 1ST CHAR OF NAME IN TBL
   C5CD   3600             MVI     M,0     ;(HL CAME BACK PT'ING TO THEAD)  CLR THIS NAME
   C5CF            CUSE2   EQU     $       ;ENTER NEW ONE IN TBL
   C5CF   7E               MOV     A,M     ;GET 1ST CHAR OF NAME
   C5D0   12               STAX    D       ;PUT NAME INTO TABLE
   C5D1   13               INX     D
   C5D2   23               INX     H
   C5D3   7E               MOV     A,M     ;GET 2ND CHAR OF NAME
   C5D4   12               STAX    D       ;NAME IS NOW POSTED
   C5D5   13               INX     D       ;PT TO 1ST BYTE OF ADDR
   C5D6   E1               POP     H       ;RESTORE SAVED RTN ADDR
   C5D7   EB               XCHG            ;DE=RTN ADDR, HL=THIS CU ENTRY
   C5D8   73               MOV     M,E     ;LO BYTE
   C5D9   23               INX     H
   C5DA   72               MOV     M,D     ;AND HI BYTE
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 28
      


   C5DB   C9               RET             ;ALL DONE
                   ;
                   ;
                   ; -*-
                   ;
                   ;
                   ;
                   ;
                   ;   THE FOLLOWING ROUTINES PROVIDE "BYTE BY BYTE" ACCESS
                   ;  TO THE CASSETTE TAPES ON EITHER A READ OR WRITE BASIS.
                   ;
                   ;  THE TAPE IS READ ONE BLOCK AT A TIME AND INDIVIDUAL
                   ;  TRANSFERS OF DATA HANDLED BY MANAGING A BUFFER AREA.
                   ;
                   ;  THE BUFFER AREA IS CONTROLLED BY A FILE CONTROL BLOCK
                   ;  (FCB) WHOSE STRUCTURE IS:
                   ;
                   ;
                   ;     7 BYTES FOR EACH OF THE TWO FILES STRUCTURED AS
                   ;   FOLLOWS:
                   ;
                   ;         1 BYTE -  ACCESS CONTROL   00 IF CLOSED
                   ;                                    FF IF READING
                   ;                                    FE IF WRITING
                   ;         1 BYTE -  READ COUNTER
                   ;         1 BYTE -  BUFFER POSITION POINTER
                   ;         2 BYTE -  CONTROL HEADER ADDRESS
                   ;         2 BYTE -  BUFFER LOCATION ADDRESS
                   ;
                   ;
                   ;
                   ;        THIS ROUTINE "OPENS" THE CASSETTE UNIT FOR ACCESS
                   ;
                   ;   ON ENTRY:  A - HAS THE TAPE UNIT NUMBER (1 OR 2)
                   ;             HL - HAS USER SUPPLIED HEADER FOR TAPE FILE
                   ;
                   ;
                   ;   NORMAL RETURN:   ALL REGISTERS ARE ALTERED
                   ;                    BLOCK IS READY FOR ACCESS
                   ;
                   ;   ERROR RETURN:    CARRY BIT IS SET
                   ;
                   ;   ERRORS:  BLOCK ALREADY OPEN
                   ;
                   ;
   C5DC   E5       BOPEN:  PUSH    H       ;SAVE HEADER ADDRESS
   C5DD   CD2FC6           CALL    LFCB    ;GET ADDRESS OF FILE CONTROL
   C5E0   C2F6C5           JNZ     TERE2   ;FILE WAS ALREADY OPEN
   C5E3   3601             MVI     M,1     ;NOW IT IS
   C5E5   23               INX     H       ;POINT TO READ COUNT
   C5E6   77               MOV     M,A     ;ZERO
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 29
      


   C5E7   23               INX     H       ;POINT TO BUFFER CURSOR
   C5E8   77               MOV     M,A     ;PUT IN THE ZERO COUNT
                   ;
                   ;  ALLOCATE THE BUFFER
                   ;
   C5E9   1163C8           LXI     D,FBUF1 ;POINT TO BUFFER AREA
   C5EC   3A54C8           LDA     FNUMF   ;GET WHICH ONE WE ARE GOING TO USE
   C5EF   82               ADD     D
   C5F0   57               MOV     D,A     ;256 BIT ADD
                   ;
   C5F1   C1       UBUF:   POP     B       ;HEADER ADDRESS
   C5F2   B7               ORA     A       ;CLEAR CARRY AND RETURN AFTER STORING PARAMS
   C5F3   C3B2C6           JMP     PSTOR   ;STORE THE VALUES
                   ;
                   ;    GENERAL ERROR RETURN POINTS FOR STACK CONTROL
                   ;
   C5F6   E1       TERE2:  POP     H
   C5F7   D1       TERE1:  POP     D
   C5F8   AF       TERE0:  XRA     A       ;CLEAR ALL FLAGS
   C5F9   37               STC             ;SET ERROR
   C5FA   C9               RET
                   ;
                   ;
   C5FB   3D       EOFER:  DCR     A       ;SET MINUS FLAGS
   C5FC   37               STC             ;AND CARRY
   C5FD   D1               POP     D       ;CLEAR THE STACK
   C5FE   C9               RET             ;THE FLAGS TELL ALL
                   ;
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE CLOSES THE FILE BUFFER TO ALLOW ACCESS
                   ;   FOR A DIFFERENT CASSETTE OR PROGRAM.  IF THE FILE
                   ;   OPERATIONS WERE "WRITE" THEN THE LAST BLOCK IS WRITTED
                   ;   OUT AND AN "END OF FILE" WRITTEN TO THE TAPE.  IF
                   ;   THE OPERATIONS WERE "READS" THEN THE FILE IS JUST
                   ;   MADE READY FOR NEW USE.
                   ;
                   ;   ON ENTRY:  A - HAS WHICH UNIT (1 OR 2)
                   ;
                   ;   ERROR RETURNS:  FILE WASN'T OPEN
                   ;
                   ;
   C5FF   CD2FC6   PCLOS:  CALL    LFCB    ;GET CONTROL BLOCK ADDRESS
   C602   C8               RZ              ;WASN'T OPEN, CARRY IS SET FROM LFCB
   C603   B7               ORA     A       ;CLEAR CARRY
   C604   3C               INR     A       ;SET CONDITION FLAGS
   C605   3600             MVI     M,0     ;CLOSE THE CONTROL BYTE
   C607   C8               RZ              ;WE WERE READING...NOTHING MORE TO DO
                   ;
                   ;    THE FILE OPERATIONS WERE "WRITES"
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 30
      


                   ;
                   ;  PUT THE CURRENT BLOCK ON THE TAPE
                   ;  (EVEN IF ONLY ONE BYTE)
                   ;  THEN WRITE AN END OF FILE TO THE TAPE
                   ;
                   ;
   C608   23               INX     H
   C609   23               INX     H
   C60A   7E               MOV     A,M     ;GET CURSOR POSITION
   C60B   7E               MOV     A,M     ;GET CURSOR POSITION
   C60C   CDBBC6           CALL    PLOAD   ;BC GET HEADER ADDRESS, DE BUFFER ADDRESS
   C60F   C5               PUSH    B       ;HEADER TO STACK
   C610   210700           LXI     H,BLKOF ;OFFSET TO BLOCK SIZE
   C613   09               DAD     B
   C614   B7               ORA     A       ;TEST COUNT
   C615   CA27C6           JZ      EOFW    ;NO BYTES...JUST WRITE EOF
                   ;
                   ;    WRITE LAST BLOCK
                   ;
   C618   E5               PUSH    H       ;SAVE BLOCK SIZE POINTER FOR EOF
   C619   77               MOV     M,A     ;PUT IN COUNT
   C61A   23               INX     H
   C61B   3600             MVI     M,0     ;ZERO THE HIGHER BYTE
   C61D   23               INX     H
   C61E   73               MOV     M,E     ;BUFFER ADDRESS
   C61F   23               INX     H
   C620   72               MOV     M,D
   C621   60               MOV     H,B
   C622   69               MOV     L,C     ;PUT HEADER ADDRESS IN HL
   C623   CD79C7           CALL    WFBLK   ;GO WRITE IT OUT
   C626   E1               POP     H       ;BLOCK SIZE POINTER
                   ;
                   ;   NOW WRITE END OF FILE TO CASSETTE
                   ;
   C627   AF       EOFW:   XRA     A       ;PUT IN ZEROS FOR SIZE:  EOF MARK IS ZERO BYTES!
   C628   77               MOV     M,A
   C629   23               INX     H
   C62A   77               MOV     M,A
   C62B   E1               POP     H       ;HEADER ADDRESS
   C62C   C379C7           JMP     WFBLK   ;WRITE IT OUT AND RETURN
                   ;
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE LOCATES THE FILE CONTROL BLOCK POINTED TO
                   ;   BY REGISTER "A".  ON RETURN HL POINT TO THE CONTROL BYT
                   ;   AND REGISTER "A" HAS THE CONTROL WORD WITH THE FLAGS
                   ;   SET FOR IMMEDIATE CONDITION DECISIONS.
                   ;
                   ;
   C62F   2155C8   LFCB:   LXI     H,FCBAS ;POINT TO THE BASE OF IT
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 31
      


   C632   1F               RAR             ;MOVE THE 1 & 2 TO 0 & 1 LIKE COMPUTERS LIKE
   C633   E601             ANI     1       ;SMALL NUMBERS ARE THE RULE
   C635   3254C8           STA     FNUMF   ;CURRENT ACCESS FILE NUMBER
   C638   CA3EC6           JZ      LFCB1   ;UNIT ONE (VALUE OF ZERO)
   C63B   215CC8           LXI     H,FCBA2 ;UNIT TWO--PT TO ITS FCB
   C63E            LFCB1   EQU     $       ;HL PT TO PROPER FCB
   C63E   7E               MOV     A,M     ;PICK UP FLAGS FM FCB
   C63F   B7               ORA     A       ;SET FLAGS BASED ON CONTROL WORD
   C640   37               STC             ;SET CARRY IN CASE OF IMMEDIATE ERROR RETURN
   C641   C9               RET
                   ;
                   ;
                   ;
                   ;
                   ;    READ TAPE BYTE ROUTINE
                   ;
                   ;    ENTRY:       -  A -  HAS FILE NUMBER
                   ;    EXIT: NORMAL -  A -  HAS BYTE
                   ;          ERROR
                   ;            CARRY SET     - IF FILE NOT OPEN OR
                   ;                            PREVIOUS OPERATIONS WERE WRITE
                   ;            CARRY & MINUS - END OF FILE ENCOUNTERED
                   ;
                   ;
                   ;
                   ;
   C642   CD2FC6   RTBYT:  CALL    LFCB    ;LOCATE THE FILE CONTROL BLOCK
   C645   C8               RZ              ;FILE NOT OPEN
   C646   3C               INR     A       ;TEST IF FF
   C647   FAF8C5           JM      TERE0   ;ERROR WAS WRITING
   C64A   36FF             MVI     M,(-1) AND 0FFH ;SET IT AS READ  (IN CASE IT WAS JUST OPENED)
   C64C   23               INX     H
   C64D   7E               MOV     A,M     ;GET READ COUNT
   C64E   E5               PUSH    H       ;SAVE COUNT ADDRESS
   C64F   23               INX     H
   C650   CDBBC6           CALL    PLOAD   ;GET THE OTHER PARAMETERS
   C653   E1               POP     H
   C654   B7               ORA     A
   C655   C271C6           JNZ     GTBYT   ;IF NOT EMPTY GO GET BYTE
                   ;
                   ;  CURSOR POSITION WAS ZERO...READ A NEW BLOCK INTO
                   ;  THE BUFFER.
                   ;
   C658   D5       RDNBLK: PUSH    D       ;BUFFER POINTER
   C659   E5               PUSH    H       ;TABLE ADDRESS
   C65A   23               INX     H
   C65B   CDA2C6           CALL    PHEAD   ;PREPARE THE HEADER FOR READ
   C65E   CDC4C6           CALL    RFBLK   ;READ IN THE BLOCK
   C661   DAF6C5           JC      TERE2   ;ERROR POP OFF STACK BEFORE RETURN
   C664   E1               POP     H
   C665   7B               MOV     A,E     ;LOW BYTE OF COUNT (WILL BE ZERO IF 256)
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 32
      


   C666   B2               ORA     D       ;SEE IF BOTH ARE ZERO
   C667   CAFBC5           JZ      EOFER   ;BYTE COUNT WAS ZERO....END OF FILE
   C66A   73               MOV     M,E     ;NEW COUNT ( ZERO IS 256 AT THIS POINT)
   C66B   23               INX     H       ;BUFFER LOCATION POINTER
   C66C   3600             MVI     M,0
   C66E   2B               DCX     H
   C66F   7B               MOV     A,E     ;COUNT TO A
   C670   D1               POP     D       ;GET BACK BUFFER ADDRESS
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE GETS ONE BYTE FROM THE BUFFER
                   ;  AND RETURNS IT IN REGISTER "A".  IF THE END
                   ;  OF THE BUFFER IS REACHED IT MOVES THE POINTER
                   ;  TO THE BEGINNING OF THE BUFFER FOR THE NEXT
                   ;  LOAD.
                   ;
   C671   3D       GTBYT:  DCR     A       ;BUMP THE COUNT
   C672   77               MOV     M,A     ;RESTORE IT
   C673   23               INX     H
   C674   7E               MOV     A,M     ;GET BUFFER POSITION
   C675   34               INR     M       ;BUMP IT
                   ;
   C676   83               ADD     E
   C677   5F               MOV     E,A     ;DE NOW POINT TO CORRECT BUFFER POSITION
   C678   D27CC6           JNC     RT1
   C67B   14               INR     D
   C67C   1A       RT1:    LDAX    D       ;GET CHARACTER FROM BUFFER
   C67D   B7               ORA     A       ;CLEAR CARRY
   C67E   C9               RET             ;ALL DONE
                   ;
                   ;
                   ;
                   ;
                   ;      THIS ROUTINE IS USED TO WRITE A BYTE TO THE FILE
                   ;
                   ;      ON ENTRY:   A -  HAS FILE NUMBER
                   ;                  B -  HAS DATA BYTE
                   ;
                   ;
   C67F   CD2FC6   WTBYT:  CALL    LFCB    ;GET CONTROL BLOCK
   C682   C8               RZ              ;FILE WASN'T OPEN
   C683   3C               INR     A
   C684   C8               RZ              ;FILE WAS READ
   C685   36FE             MVI     M,0FEH  ;SET IT TO WRITE
   C687   23               INX     H
   C688   23               INX     H
   C689   78               MOV     A,B     ;GET CHARACTER
   C68A   F5               PUSH    PSW
   C68B   E5               PUSH    H       ;SAVE CONTROL ADDRESS+2
                   ;
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 33
      


                   ;   NOW DO THE WRITE
                   ;
   C68C   CDBBC6           CALL    PLOAD   ;BC GETS HEADER ADDR, DE BUFFER ADDRESS
   C68F   E1               POP     H
   C690   7E               MOV     A,M     ;COUNT BYTE
   C691   83               ADD     E
   C692   5F               MOV     E,A
   C693   D297C6           JNC     WT1
   C696   14               INR     D
   C697   F1       WT1:    POP     PSW     ;CHARACTER
   C698   12               STAX    D       ;PUT CHR IN BUFFER
   C699   B7               ORA     A       ;CLEAR FLAGS
   C69A   34               INR     M       ;INCREMENT THE COUNT
   C69B   C0               RNZ             ;RETURN IF COUNT DIDN'T ROLL OVER
                   ;
                   ;   THE BUFFER IS FULL. WRITE IT TO TAPE AND RESET
                   ;  CONTROL BLOCK.
                   ;
   C69C   CDA2C6           CALL    PHEAD   ;PREPARE THE HEADER
   C69F   C379C7           JMP     WFBLK   ;WRITE IT OUT AND RETURN
                   ;
                   ;
                   ;
                   ;
                   ;  THIS ROUTINE PUTS THE BLOCK SIZE (256) AND BUFFER
                   ;  ADDRESS IN THE FILE HEADER.
                   ;
   C6A2   CDBBC6   PHEAD:  CALL    PLOAD   ;GET HEADER AND BUFFER ADDRESSES
   C6A5   C5               PUSH    B       ;HEADER ADDRESS
   C6A6   210600           LXI     H,BLKOF-1 ;PSTOR DOES AN INCREMENT
   C6A9   09               DAD     B       ;HL POINT TO BLOCKSIZE ENTRY
   C6AA   010001           LXI     B,256
   C6AD   CDB2C6           CALL    PSTOR
   C6B0   E1               POP     H       ;HL RETURN WITH HEADER ADDRESS
   C6B1   C9               RET
                   ;
                   ;
   C6B2   23       PSTOR:  INX     H
   C6B3   71               MOV     M,C
   C6B4   23               INX     H
   C6B5   70               MOV     M,B
   C6B6   23               INX     H
   C6B7   73               MOV     M,E
   C6B8   23               INX     H
   C6B9   72               MOV     M,D
   C6BA   C9               RET
                   ;
                   ;
   C6BB   23       PLOAD:  INX     H
   C6BC   4E               MOV     C,M
   C6BD   23               INX     H
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 34
      


   C6BE   46               MOV     B,M
   C6BF   23               INX     H
   C6C0   5E               MOV     E,M
   C6C1   23               INX     H
   C6C2   56               MOV     D,M
   C6C3   C9               RET
                   ;
                   ;
                   ;
                   ;
                   ;
                   ;   THIS ROUTINE SETS THE CORRECT UNIT FOR SYSTEM READS
   C6C4   CDDCC7   RFBLK:  CALL    GTUNT   ;SET UP A=UNIT WITH SPEED
                   ;
                   ;
                   ;
                   ;
                   ;              TAPE READ ROUTINES
                   ;
                   ;     ON-ENTRY:     A HAS UNIT AND SPEED
                   ;                   HL POINT TO HEADER BLOCK
                   ;                   DE HAVE OPTIONAL PUT ADDRESS
                   ;
                   ;     ON EXIT:      CARRY IS SET IF ERROR OCCURED
                   ;                   TAPE UNITS ARE OFF
                   ;
                   ;
   C6C7   D5       RTAPE:  PUSH    D       ;SAVE OPTIONAL ADDRESS
   C6C8   0603             MVI     B,3     ;SHORT DELAY
   C6CA   CDEDC7           CALL    TON
   C6CD   DB07             IN      TDATA   ;CLEAR THE UART FLAGS
                   ;
   C6CF   E5       PTAP1:  PUSH    H       ;HEADER ADDRESS
   C6D0   CD1FC7           CALL    RHEAD   ;GO READ HEADER
   C6D3   E1               POP     H
   C6D4   DA02C7           JC      TERR    ;IF AN ERROR OR ESC WAS RECEIVED
   C6D7   C2CFC6           JNZ     PTAP1   ;IF VALID HEADER NOT FOUND
                   ;
                   ;  FOUND A VALID HEADER NOW DO COMPARE
                   ;
   C6DA   E5               PUSH    H       ;GET BACK AND RESAVE ADDRESS
   C6DB   111CC8           LXI     D,THEAD
   C6DE   CDD0C7           CALL    DHCMP   ;COMPARE DE-HL HEADERS
   C6E1   E1               POP     H
   C6E2   C2CFC6           JNZ     PTAP1
                   ;
                   ;
   C6E5   D1               POP     D       ;OPTIONAL "PUT" ADDRESS
   C6E6   7A               MOV     A,D
   C6E7   B3               ORA     E       ;SEE IF DE IS ZERO
   C6E8   2A23C8           LHLD    BLOCK   ;GET BLOCK SIZE
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 35
      


   C6EB   EB               XCHG            ;...TO DE
                   ;  DE HAS HBLOCK....HL HAS USER OPTION
   C6EC   C2F2C6           JNZ     RTAP    ;IF DE WAS ZERO GET TAPE LOAD ADDRESS
   C6EF   2A25C8           LHLD    LOADR   ;GET TAPE LOAD ADDRESS
                   ;
                   ;
                   ;     THIS ROUTINE READS "DE" BYTES FROM THE TAPE
                   ;     TO ADDRESS HL.  THE BYTES MUST BE FROM ONE
                   ;     CONTIGUOUS PHYSICAL BLOCK ON THE TAPE.
                   ;
                   ;          HL HAS "PUT" ADDRESS
                   ;          DE HAS SIZE OF TAPE BLOCK
                   ;
   C6F2   D5       RTAP:   PUSH    D       ;SAVE SIZE FOR RETURN TO CALLING PROGRAM
                   ;
   C6F3            RTAP2   EQU     $       ;HERE TO LOOP RDING BLKS
   C6F3   CD11C7           CALL    DCRCT   ;DROP COUNT, B=LEN THIS BLK
   C6F6   CA0CC7           JZ      RTOFF   ;ZERO=ALL DONE
                   ;
   C6F9   CD40C7           CALL    RHED1   ;READ THAT MANY BYTES
   C6FC   DA02C7           JC      TERR    ;IF ERROR OR ESC
   C6FF   CAF3C6           JZ      RTAP2   ;RD OK--READ SOME MORE
                   ;
                   ;  ERROR RETURN
                   ;
   C702   AF       TERR:   XRA     A
   C703   37               STC             ;SET ERROR FLAGS
   C704   C30DC7           JMP     RTOF1
                   ;
                   ;
   C707   0601     TOFF:   MVI     B,1
   C709   CDEFC7           CALL    DELAY
   C70C   AF       RTOFF:  XRA     A
   C70D   D306     RTOF1:  OUT     TAPPT
   C70F   D1               POP     D       ;RETURN BYTE COUNT
   C710   C9               RET
                   ;
                   ;
   C711            DCRCT   EQU     $       ;COMMON RTN TO COUNT DOWN BLK LENGTHS
   C711   AF               XRA     A       ;CLR FOR LATER TESTS
   C712   47               MOV     B,A     ;SET THIS BLK LEN=256
   C713   B2               ORA     D       ;IS AMNT LEFT < 256
   C714   C21CC7           JNZ     DCRC2   ;NO--REDUCE AMNT BY 256
   C717   B3               ORA     E       ;IS ENTIRE COUNT ZERO
   C718   C8               RZ              ;ALL DONE--ZERO=THIS CONDITION
   C719   43               MOV     B,E     ;SET THIS BLK LEN TO AMNT REMAINING
   C71A   5A               MOV     E,D     ;MAKE ENTIRE COUNT ZERO NOW
   C71B   C9               RET             ;ALL DONE (NON-ZERO FLAG)
   C71C            DCRC2   EQU     $       ;REDUCE COUNT BY 256
   C71C   15               DCR     D       ;DROP BY 256
   C71D   B7               ORA     A       ;FORCE NON-ZERO FLAG
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 36
      


   C71E   C9               RET             ;NON-ZERO=NOT DONE YET (BLK LEN=256)
                   ;
                   ;
                   ;   READ THE HEADER
                   ;
   C71F   060A     RHEAD:  MVI     B,10    ;FIND 10 NULLS
   C721   CD59C7   RHEA1:  CALL    STAT
   C724   D8               RC              ;IF ESCAPE
   C725   DB07             IN      TDATA   ;IGNORE ERROR CONDITIONS
   C727   B7               ORA     A       ;ZERO?
   C728   C21FC7           JNZ     RHEAD
   C72B   05               DCR     B
   C72C   C221C7           JNZ     RHEA1   ;LOOP UNTIL 10 IN A ROW
                   ;
                   ;    WAIT FOR THE START CHARACTER
                   ;
   C72F   CD6CC7   SOHL:   CALL    TAPIN
   C732   D8               RC              ;ERROR OR ESCAPE
   C733   FE01             CPI     1       ;ARE WE AT THE 01 YET (START CHAR)
   C735   DA2FC7           JC      SOHL    ;NO, BUT STIL ZEROES
   C738   C21FC7           JNZ     RHEAD   ;NO, LOOK FOR ANOTHER 10 NULLS
                   ;
                   ;    WE HAVE  10 (OR MORE) NULLS FOLLOWED IMMEDIATELY
                   ;    BY AN 01.  NOW READ THE HEADER.
                   ;
   C73B   211CC8           LXI     H,THEAD ;POINT TO BUFFER
   C73E   0610             MVI     B,HLEN  ;LENGTH TO READ
                   ;
   C740            RHED1   EQU     $       ;RD A BLOCK INTO HL FOR B BYTES
   C740   0E00             MVI     C,0     ;INIT THE CRC
   C742            RHED2   EQU     $       ;LOOP HERE
   C742   CD6CC7           CALL    TAPIN   ;GET A BYTE
   C745   D8               RC
   C746   77               MOV     M,A     ;STORE IT
   C747   23               INX     H       ;INCREMENT ADDRESS
   C748   CDA6C7           CALL    DOCRC   ;GO COMPUTE THE CRC
   C74B   05               DCR     B       ;WHOLE HEADER YET?
   C74C   C242C7           JNZ     RHED2   ;DO ALL THE BYTES
                   ;
                   ;   THIS ROUTINE GETS THE NEXT BYTE AND COMPARES IT
                   ; TO THE VALUE IN REGISTER C.  THE FLAGS ARE SET ON
                   ; RETURN.
                   ;
   C74F   CD6CC7           CALL    TAPIN   ;GET CRC BYTE
   C752   A9               XRA     C       ;CLR CARRY AND SET ZERO IF MATCH, ELSE NON-ZERO
   C753   C8               RZ              ;CRC IS FINE
   C754   3A11C8           LDA     IGNCR   ;BAD CRC, SHD WE STILL ACCEPT IT
   C757   3C               INR     A       ;SEE IF IT WAS FF, IF FF THEN ZERO SAYS IGN ERR
                   ;   NOW, CRC ERR DETECTION DEPENDS ON IGNCR.
   C758   C9               RET
                   ;
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 37
      


                   ;    THIS ROUTINE GETS THE NEXT AVAILABLE BYTE FROM THE
                   ;  TAPE.  WHILE WAITING FOR THE BYTE THE KEYBOARD IS TESTED
                   ;  FOR AN ESC COMMAND.  IF RECEIVED THE TAPE LOAD IS
                   ;  TERMINATED AND A RETURN TO THE COMMAND MODE IS MADE.
                   ;
   C759   DB06     STAT:   IN      TAPPT   ;TAPE STATUS PORT
   C75B   2F               CMA             ;*UM* MITS ACR USES ACTIVE LOW
   C75C   E601             ANI     TDR
   C75E   C0               RNZ
   C75F   CD1FC0           CALL    SINP    ;CHECK INPUT
   C762   CA59C7           JZ      STAT    ;NOTHING THERE YET
   C765   E67F             ANI     7FH     ;CLEAR PARITY 1ST
   C767   C259C7           JNZ     STAT    ;EITHER MODE OR CTL-@
   C76A   37               STC             ;SET ERROR FLAG
   C76B   C9               RET             ;AND RETURN
                   ;
                   ;
                   ;
   C76C   CD59C7   TAPIN:  CALL    STAT    ;WAIT UNTIL A CHARACTER IS AVAILABLE
   C76F   D8               RC
                   ;
   C770   DB06     TREDY:  IN      TAPPT   ;TAPE STATUS
   C772   E618             ANI     TFE+TOE ;DATA ERROR?
   C774   DB07             IN      TDATA   ;GET THE DATA
   C776   C8               RZ              ;IF NO ERRORS
   C777   37               STC             ;SET ERROR FLAG
   C778   C9               RET
                   ;
                   ;
                   ;  THIS ROUTINE GETS THE CORRECT UNIT FOR SYSTEM WRITES
   C779   CDDCC7   WFBLK:  CALL    GTUNT   ;SET UP A WITH UNIT AND SPEED
                   ;
                   ;
                   ;
                   ;       WRITE TAPE BLOCK ROUTINE
                   ;
                   ;   ON ENTRY:   A   HAS UNIT AND SPEED
                   ;              HL   HAS POINTER TO HEADER
                   ;
                   ;
   C77C            WTAPE   EQU     $       ;HERE TO WRITE TAPE
   C77C   E5               PUSH    H       ;SAVE HEADER ADDRESS
   C77D   CDADC7           CALL    WHEAD   ;TURN ON, THEN WRITE HDR
   C780   E1               POP     H
   C781   110700           LXI     D,BLKOF ;OFFSET TO BLOCK SIZE IN HEADER
   C784   19               DAD     D       ;HL POINT TO BLOCK SIZE
   C785   5E               MOV     E,M
   C786   23               INX     H
   C787   56               MOV     D,M     ;DE HAVE SIZE
   C788   23               INX     H
   C789   7E               MOV     A,M
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 38
      


   C78A   23               INX     H
   C78B   66               MOV     H,M
   C78C   6F               MOV     L,A     ;HL HAVE STARTING ADDRESS
                   ;
                   ;    THIS ROUTINE WRITES ONE PHYSICAL BLOCK ON THE
                   ;  TAPE "DE" BYTES LONG FROM ADDRESS "HL".
                   ;
                   ;
   C78D            WTAP1   EQU     $       ;HERE FOR THE EXTRA PUSH
   C78D   E5               PUSH    H       ;A DUMMY PUSH FOR LATER EXIT
   C78E            WTAP2   EQU     $       ;LOOP HERE UNTIL ENTIRE AMOUNT READ
   C78E   CD11C7           CALL    DCRCT   ;DROP COUNT IN DE AND SET UP B W/LEN THIS BLK
   C791   CA07C7           JZ      TOFF    ;RETURNS ZERO IF ALL DONE
   C794   CDC1C7           CALL    WTBL    ;WRITE BLOCK FOR BYTES IN B (256)
   C797   C38EC7           JMP     WTAP2   ;LOOP UNTIL ALL DONE
                   ;
                   ;
   C79A   F5       WRTAP:  PUSH    PSW
   C79B   DB06     WRWAT:  IN      TAPPT   ;TAPE STATUS
   C79D   2F               CMA             ;*UM* MITS ACR USES ACTIVE LOW
   C79E   E680             ANI     TTBE    ;IS TAPE READY FOR A CHAR YET
   C7A0   CA9BC7           JZ      WRWAT   ;NO--WAIT
   C7A3   F1               POP     PSW     ;YES--RESTORE CHAR TO OUTPUT
   C7A4   D307             OUT     TDATA   ;SEND CHAR TO TAPE
                   ;
   C7A6            DOCRC   EQU     $       ;A COMMON CRC COMPUTATION ROUTINE
   C7A6   91               SUB     C
   C7A7   4F               MOV     C,A
   C7A8   A9               XRA     C
   C7A9   2F               CMA
   C7AA   91               SUB     C
   C7AB   4F               MOV     C,A
   C7AC   C9               RET             ;ONE  BYTE NOW WRITTEN
                   ;
                   ;
                   ;   THIS ROUTINE WRITES THE HEADER POINTED TO BY
                   ;   HL TO THE TAPE.
                   ;
   C7AD            WHEAD   EQU     $       ;HERE TO 1ST TURN ON THE TAPE
   C7AD   CDEBC7           CALL    WTON    ;TURN IT ON, THEN WRITE HEADER
   C7B0   1632             MVI     D,50    ;WRITE 50 ZEROS
   C7B2   AF       NULOP:  XRA     A
   C7B3   CD9AC7           CALL    WRTAP
   C7B6   15               DCR     D
   C7B7   C2B2C7           JNZ     NULOP
                   ;
   C7BA   3E01             MVI     A,1
   C7BC   CD9AC7           CALL    WRTAP
   C7BF   0610             MVI     B,HLEN  ;LENGTH TO WRITE OUT
                   ;
   C7C1   0E00     WTBL:   MVI     C,0     ;RESET CRC BYTE
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 39
      


   C7C3   7E       WLOOP:  MOV     A,M     ;GET CHARACTER
   C7C4   CD9AC7           CALL    WRTAP   ;WRITE IT TO THE TAPE
   C7C7   05               DCR     B
   C7C8   23               INX     H
   C7C9   C2C3C7           JNZ     WLOOP
   C7CC   79               MOV     A,C     ;GET CRC
   C7CD   C39AC7           JMP     WRTAP   ;PUT IT ON THE TAPE AND RETURN
                   ;
                   ;
                   ;   THIS ROUTINE COMPARES THE HEADER IN THEAD TO
                   ;   THE USER SUPPLIED HEADER IN ADDRESS HL.
                   ;   ON RETURN IF ZERO IS SET THE TWO NAMES COMPARED
                   ;
   C7D0   0605     DHCMP:  MVI     B,5
   C7D2   1A       DHLOP:  LDAX    D
   C7D3   BE               CMP     M
   C7D4   C0               RNZ
   C7D5   05               DCR     B
   C7D6   C8               RZ              ;IF ALL FIVE COMPARED
   C7D7   23               INX     H
   C7D8   13               INX     D
   C7D9   C3D2C7           JMP     DHLOP
                   ;
   C7DC            GTUNT   EQU     $       ;SET A=SPEED + UNIT
   C7DC   3A54C8           LDA     FNUMF   ;GET UNIT
   C7DF   B7               ORA     A       ;SEE WHICH UNIT
   C7E0   3A0DC8           LDA     TSPD    ;BUT 1ST GET SPEED
   C7E3   C2E8C7           JNZ     GTUN2   ;MAKE IT UNIT TWO
   C7E6   C640             ADI     TAPE2   ;THIS ONCE=UNIT 2, TWICE=UNIT 1
   C7E8   C640     GTUN2:  ADI     TAPE2   ;UNIT AND SPEED NOW SET IN A
   C7EA   C9               RET             ;ALL DONE
                   ;
   C7EB   0604     WTON:   MVI     B,4     ;SET LOOP DELAY  (BIT LONGER ON A WRITE)
   C7ED            TON     EQU     $       ;HERE TO TURN A TAPE ON THEN DELAY
   C7ED   D306             OUT     TAPPT   ;GET TAPE MOVING, THEN DELAY
                   ;
   C7EF   110000   DELAY:  LXI     D,0
   C7F2   1B       DLOP1:  DCX     D
   C7F3   7A               MOV     A,D
   C7F4   B3               ORA     E
   C7F5   C2F2C7           JNZ     DLOP1
   C7F8   05               DCR     B
   C7F9   C2EFC7           JNZ     DELAY
   C7FC   C9               RET
                   ;
                   ;
                   ;**** -- END OF PROGRAM--
                   ;
                   ;
                   ;
                   ;
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 40
      


                   ;    S Y S T E M    E Q U A T E S
                   ;
                   ;
                   ;          VDM PARAMETERS
                   ;
   CC00            VDMEM   EQU     0CC00H  ;VDM SCREEN MEMORY
                   ;
                   ;
                   ;            KEYBOARD SPECIAL KEY ASSIGNMENTS
                   ;
                   ;  THESE DEFINITIONS ARE DESIGNED TO ALLOW
                   ;  COMPATABILITY WITH SOLOS(TM). THESE ARE THE
                   ;  SAME KEYS WITH BIT 7 (X'80') STRIPPED OFF.
                   ;
   001A            DOWN    EQU     1AH     ;CTL Z
   0017            UP      EQU     17H     ;CTL W
   0001            LEFT    EQU     01H     ;CTL A
   0013            RIGHT   EQU     13H     ;CTL S
   000B            CLEAR   EQU     0BH     ;CTL K
   000E            HOME    EQU     0EH     ;CTL N
   0000            MODE    EQU     00H     ;CTL-@
                   ;BACKS   EQU     5FH     ;BACKSPACE
   0008            BACKS   EQU     08H     ;*UM*
   000A            LF      EQU     10
   000D            CR      EQU     13
   0020            BLANK   EQU     ' '
   0020            SPACE   EQU     BLANK
   0018            CX      EQU     'X'-40H
   001B            ESC     EQU     1BH
                   ;
                   ;          PORT ASSIGNMENTS
                   ;
   0000            STAPT   EQU     0       ;STATUS PORT GENERAL
                   ;STKBD   EQU     STAPT   ;PROCTEC 3P+S
   0004            STKBD   EQU     4       ;*UM* MITS PIO
   0001            SDATA   EQU     1       ;SERIAL DATA
   0012            SIO2S   EQU     18      ;*UM* STATUS SIO2 B
   0013            SIO2D   EQU     19      ;*UM* DATA SIO2 B
   0002            PDATA   EQU     2       ;PARALLEL DATA
                   ;KDATA   EQU     3       ;KEYBOARD DATA PROCTEC 3P+S
   0005            KDATA   EQU     5       ;*UM* KEYBOARD DATA MITS PIO
   00C8            DSTAT   EQU     0C8H    ;VDM CONTROL PORT
                   ;TAPPT   EQU     0FAH    ;TAPE STATUS PORT PROCTEC SOL-20
   0006            TAPPT   EQU     06H     ;*UM* TAPE STATUS PORT MITS ACR
                   ;TDATA   EQU     0FBH    ;TAPE DATA PORT PROCTEC SOL-20
   0007            TDATA   EQU     07H     ;*UM* TAPE DATA PORT MITS ACR
   00FF            SENSE   EQU     0FFH    ;SENSE SWITCHES
                   ;
                   ;
                   ;
                   ;          BIT ASSIGNMENT MASKS
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 41
      


                   ;
   0001            SCD     EQU     1       ;SERIAL CARRIER DETECT
   0002            SDSR    EQU     2       ;SERIAL DATA SET READY
   0004            SPE     EQU     4       ;SERIAL PARITY ERROR
   0008            SFE     EQU     8       ;SERIAL FRAMING ERROR
   0010            SOE     EQU     16      ;SERIAL OVERRUN ERROR
   0020            SCTS    EQU     32      ;SERIAL CLEAR TO SEND
                   ;SDR     EQU     64      ;SERIAL DATA READY PROCTEC 3P+S
   0001            SDR     EQU     1       ;*UM* SERIAL DATA READY MITS SIO
   0001            SDR2    EQU     1       ;*UM* SERIAL DATA READY MITS 2SIO
                   ;STBE    EQU     128     ;SERIAL TRANSMITTER BUFFER EMPTY PROCTEC 3P+S
   0080            STBE    EQU     128     ;*UM* SERIAL TRANSMITTER BUFFER EMPTY MITS SIO
   0002            STBE2   EQU     2       ;*UM* SERIAL TRANSMITTER BUFFER EMPTY MITS 2SIO
                   ;
   0001            KDR     EQU     1       ;KEYBOARD DATA READY
   0002            PDR     EQU     2       ;PARALLEL DATA READY
   0004            PXDR    EQU     4       ;PARALLEL DEVICE READY
                   ;TFE     EQU     8       ;TAPE FRAMING ERROR PROCTEC CUTS
   0010            TFE     EQU     16      ;*UM* TAPE FRAMING ERROR MITS ACR
                   ;TOE     EQU     16      ;TAPE OVERFLOW ERROR PROCTEC CUTS
   0008            TOE     EQU     8       ;*UM* TAPE OVERFLOW ERROR MITS ACR
                   ;TDR     EQU     64      ;TAPE DATA READY PROCTEC CUTS
   0001            TDR     EQU     1       ;*UM* TAPE DATA READY MITS ACR
   0080            TTBE    EQU     128     ;TAPE TRANSMITTER BUFFER EMPTY
                   ;
   0001            SOK     EQU     1       ;SCROLL OK FLAG
                   ;
   0080            TAPE1   EQU     80H     ;1=TURN TAPE ONE ON
   0040            TAPE2   EQU     40H     ;1=TURN TAPE TWO ON
                   ;
                   ;
                   ;
                   ;
                   ;       S Y S T E M   G L O B A L    A R E A
                   ;
   C800                    ORG    START+0800H ;RAM STARTS JUST AFTER ROM
                   ;
   C800            SYSRAM  EQU     $       ;START OF SYSTEM RAM
   CBFF            SYSTP   EQU     SYSRAM+3FFH ;STACK WORKS FM TOP DOWN
                   ;
                   ;
                   ;   PARAMETERS STORED IN RAM
                   ;
   C800            UIPRT:  DS      2       ;USER DEFINED INPUT RTN IF NON ZERO
   C802            UOPRT:  DS      2       ;USER DEFINED OUTPUT RTN IF NON ZERO
   C804            DFLTS:  DS      2       ;DEFAULT PSUEDO I/O PORTS
   C806            IPORT:  DS      1       ;CRNT INPUT PSUEDO PORT
   C807            OPORT:  DS      1       ;CRNT OUTPUT PSUEDO PORT
   C808            NCHAR:  DS      1       ;CURRENT CHARACTER POSITION
   C809            LINE:   DS      1       ;CURRENT LINE POSITION
   C80A            BOT:    DS      1       ;BEGINNING OF TEXT DISPLACEMENT
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 42
      


   C80B            SPEED:  DS      1       ;SPEED CONTROL BYTE
   C80C            ESCFL:  DS      1       ;ESCAPE FLAG CONTROL BYTE
   C80D            TSPD:   DS      1       ;CURRENT TAPE SPEED
   C80E            INPTR:  DS      2       ;PTR TO NEXT CHAR POSITION IN INLIN
   C810            NUCNT:  DS      1       ;NUMBER OF NULLS AFTER CRLF
   C811            IGNCR:  DS      1       ;IGN CRC ERR FLAG, FF=IGN CRC ERRS, ELSE=NORMAL
                   ;
   C812                    DS      10      ;ROOM FOR FUTURE EXPANSION
                   ;
                   ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
                   ;    T H I S   I S   T H E   H E A D E R   L A Y O U T    *
                   ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
                   ;
   C81C            THEAD:  DS      5       ;NAME
   C821                    DS      1       ;THIS BYTE MUST BE ZERO
   C822            HTYPE:  DS      1       ;TYPE
   C823            BLOCK:  DS      2       ;BLOCK SIZE
   C825            LOADR:  DS      2       ;LOAD ADDRESS
   C827            XEQAD:  DS      2       ;AUTO EXECUTE ADDRESS
   C829            HSPR:   DS      3       ;SPARES
                   ;
   0010            HLEN    EQU     $-THEAD ;LENGTH OF HEADER
   0007            BLKOF   EQU     BLOCK-THEAD ;OFFSET TO BLOCK SIZE
   C82C            DHEAD:  DS      HLEN    ;A DUMMY HDR FOR COMPARES WHILE RD'ING
                   ;
                   ;
   C83C            CUTAB:  DS      6*4     ;ROOM FOR UP TO 6 CUSTOM USER COMMANDS
                   ;
                   ;
   C854            FNUMF:  DS      1       ;FOR CURRENT FILE OPERATIONS
   C855            FCBAS:  DS      7       ;1ST FILE CONTROL BLOCK
   C85C            FCBA2:  DS      7       ;2ND FILE CONTROL BLOCK
   C863            FBUF1:  DS      2*256   ;SYSTEM FILE BUFFER BASE
   CA63                    DS      1       ;"BELL" (X'07') FLAGS START OF INPUT BFR
   CA64            INLIN:  DS      80      ;ROOM FOR THE INPUT LINE
   CAB4            USARE   EQU     $       ;START OF USER AREA
                   ;
                   ;   REMEMBER THAT THE STACK WORKS ITS WAY DOWN-FROM
                   ;   THE END OF THIS 1K RAM AREA.
                   ;
                   ; -*-
                           END
 NO PROGRAM ERRORS
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 43
      


                        SYMBOL TABLE

  * 01

  A      0007      ADOUT  C3D9      AINP   C022 *    ALOAD  C544      
  AOUT   C01C *    ARET   C1C3 *    ARET1  C1C5      ARET2  C1CA      
  B      0000      BACKS  0008      BLANK  0020      BLKOF  0007      
  BLOCK  C823      BOPEN  C5DC      BOT    C80A      BOUT   C3F7      
  C      0001      CHAR   C0B8      CHRLI  C56D      CLEAR  000B      
  CLERA  C1DC      CLIN1  C123      CLIN2  C118      CLINE  C11D *    
  COMN1  C215      COMND  C218      COMTA  C2BD      CONT   C264 *    
  COPRC  C26A      CR     000D      CREM   C15F      CRLF   C342      
  CSET   C576      CUR    C0F5      CURET  C1CE      CURSC  C0F3      
  CUSE2  C5CF      CUSET  C5B9      CUTAB  C83C      CX     0018 *    
  D      0002      DCRC2  C71C      DCRCT  C711      DEFLT  C494      
  DELAY  C7EF      DFLTS  C804      DHCMP  C7D0      DHEAD  C82C      
  DHLOP  C7D2      DISP0  C282      DISP1  C28B      DISPD  C595      
  DISPT  C287      DLOOP  C3B6      DLOP1  C7F2      DLP1   C3C1      
  DLP1A  C3D0      DOCRC  C7A6      DOWN   001A      DSTAT  00C8      
  DUMP   C3AD      E      0003      ENLO1  C427      ENLO3  C444      
  ENLOP  C418      ENTER  C414      EOFER  C5FB      EOFW   C627      
  ERAS1  C0FF      ERAS3  C112      ERR1   C46B      ERR2   C46C      
  ERRIT  C065      ERRM   C521      ERRO1  C070      ERROT  C06C      
  ESC    001B      ESCFL  C80C      ESCS   C187      ESCSP  C190      
  EXEC   C449      EXEC1  C44C      FBUF1  C863      FCBA2  C85C      
  FCBAS  C855      FCLOS  C00A *    FDCOM  C291      FDCOU  C28E      
  FNUMF  C854      FOPEN  C007 *    GCLI0  C227      GCLI1  C232      
  GCLI2  C25F      GCLI3  C261      GCLIN  C239      GOBAC  C08F      
  GOBK   C0A0      GTBYT  C671      GTUN2  C7E8      GTUNT  C7DC      
  H      0004      HBOUT  C3DE      HCONV  C38B *    HCOV1  C39B      
  HEOU1  C405      HEOUT  C3FC      HLEN   0010      HOME   000E      
  HSPR   C829 *    HTYPE  C822      IGNCR  C811      INIT   C001 *    
  INLIN  CA64      INPTR  C80E      IOPRC  C026      IPORT  C806      
  ITAB   C309      KDATA  0005      KDR    0001      KREA1  C035      
  L      0005      LEFT   0001      LF     000A      LFCB   C62F      
  LFCB1  C63E      LINE   C809      LIST1  C535      LLIST  C52D      
  LOADR  C825      M      0006      MODE   0000 *    NAME   C454      
  NAME0  C451      NAME1  C459      NAOUT  C54C      NCHAR  C808      
  NCOM   C2A3      NEXT   C0A4      NFIL   C480      NLOOP  C566      
  NUCNT  C810      NULOP  C7B2      NULOT  C350      OCHAR  C0BC      
  OK     C0E5      OPORT  C807      OTAB   C301      OUTH   C410      
  OUTPR  C02E      PARIT  C052      PAROT  C05A      PBACK  C167      
  PCLOS  C5FF      PCR    C170      PCUR   C138      PDATA  0002 *    
  PDOWN  C0EF      PDR    0002 *    PERSE  C0F9      PESC   C181      
  PHEAD  C6A2      PHOME  C109      PLEFT  C134      PLF    C175      
  PLOAD  C6BB      PRIT   C13E      PROMP  C33A      PSCAN  C3A5      
  PSTOR  C6B2      PSW    0006      PTAP1  C6CF      PUP    C12D      
  PXDR   0004 *    RDBLK  C013 *    RDBYT  C00D *    RDNBL  C658 *    
  RETRN  C004 *    RFBLK  C6C4      RHEA1  C721      RHEAD  C71F      
  RHED1  C740      RHED2  C742      RIGHT  0013      RT1    C67C      
  RTAP   C6F2      RTAP2  C6F3      RTAPE  C6C7      RTBYT  C642      
1
 8080 MACRO ASSEMBLER, VER 3.0        ERRORS = 0      
+                                                      19:09  05/27/2017
+                                                                                      PAGE 44
                              SYMBOL TABLE


  RTOF1  C70D      RTOFF  C70C      SBLK   C359      SBLK1  C35B      
  SCD    0001 *    SCHR   C36C      SCHR1  C36E      SCONV  C378      
  SCROL  C0D0 *    SCTS   0020 *    SDATA  0001      SDR    0001      
  SDR2   0001      SDSR   0002 *    SECON  C1B8      SENSE  00FF      
  SEROT  C047      SETAB  C311      SETCI  C5A1      SETCO  C5A5      
  SETCR  C5B5      SETIN  C599      SETNU  C5B1      SETOT  C59D      
  SETSP  C590      SETTY  C5A9      SETX   C1B0      SETXQ  C5AD      
  SETY   C1B4      SFE    0008 *    SHE1   C381      SHEX   C37E      
  SINP   C01F      SIO2D  0013      SIO2S  0012      SOE    0010 *    
  SOHL   C72F      SOK    0001 *    SOUT   C019      SP     0006      
  SPACE  0020      SPE    0004 *    SPEED  C80B      SREA1  C03E      
  SROL   C0D4      STAPT  0000      START  C000      STAT   C759      
  STBE   0080      STBE2  0002      STKBD  0004      STRTA  C1D7      
  STRTB  C1F4      STRTC  C1FF      STRTD  C20F      STSPD  C594      
  STUNT  C49C      STUP   C2AA      SYSRA  C800      SYSTP  CBFF      
  TAERR  C510      TAPE1  0080      TAPE2  0040      TAPIN  C76C      
  TAPPT  0006      TASPD  C58A      TBL    C2E2      TDATA  0007      
  TDR    0001      TERE0  C5F8      TERE1  C5F7 *    TERE2  C5F6      
  TERR   C702      TFE    0010      THEAD  C81C      TIMER  C09B      
  TLIST  C527      TLOA2  C4AF *    TLOA3  C4BB      TLOAD  C4A1      
  TOE    0008      TOFF   C707      TON    C7ED      TREDY  C770 *    
  TSAVE  C4E0      TSPD   C80D      TSRCH  C0A6      TTBE   0080      
  TXEQ   C4A0      UBUF   C5F1 *    UIPRT  C800      UOPRT  C802      
  UP     0017      USARE  CAB4 *    VDAD   C14C      VDAD2  C149      
  VDADD  C145      VDM01  C078      VDMEM  CC00      WFBLK  C779      
  WHEAD  C7AD      WLOOP  C7C3      WRBLK  C016 *    WRBYT  C010 *    
  WRTAP  C79A      WRWAT  C79B      WT1    C697      WTAP1  C78D      
  WTAP2  C78E      WTAPE  C77C      WTBL   C7C1      WTBYT  C67F      
  WTLP1  C3F1      WTON   C7EB      XEQAD  C827      

