; 300 To 2000 BAUD LOADER PROGRAM
; (C) 1981 Jay Fenton for Astrovision Inc.
;
; ********************************************************
;
; Typed in on Dec. 16, 2007 by Adam Trionfo
;
; Compile with Zmac using:
;
; zmac -i -m -o 300-2000.bin -x 300-2000.lst 300-2000.asm
;
; See comments at end of program [for version info]
;
; ********************************************************
;
; This program loads audio tapes generated by the old
; version of BALLY BASIC into the New and Improved version
; of BALLY BASIC.
;
; Operating Instructions
;
; 1)    Load the LOADER PROGRAM into memory using the :RUN
;       command. When loaded the screen background
;       brightness will change continuously.
; 2)    Cue up the 300 baud tape and PLAY it.
; 3)    Press the GO key to release the LOADER PROGRAM.
; 4)    Observe the program statements accumulating in
;       the buffer just below the program zone. The screen
;       will reveal the scratchpad during this phase.
; 5)    Program loading will stop on any of the following
;       conditions:
;       a) :RETURN is found in an unnumbered line.
;       b) RUN is found in an unnumbered line.
;       c) The HALT key is pressed, in which case we
;          proceed to end loading.
;       d) Any other key in the column beneath HALT
;          is pressed.
;       Cases a), b), and d) cause the program to go
;       back to step 2)
;       If no more segments are to be loaded, press
;       HALT to proceed to final loading.
; 6)    After HALT is pressed the program will convert the
;       statements in the buffer into the representation
;       used within BALLY BASIC. This is done by moving
;       the buffer to the highest possible address and
;       using special I/O routines which feed characters
;       from this buffer to the BALLY BASIC input routines.
;       This will be seen on the screen as a race between
;       the input buffer and the program storage area.
; 7)    The LOADER PROGRAM will then exit to BALLY BASIC.
;       The variables A-Z will be zeroed out, and the screen
;       will be cleared. The program may now be executed or
;       written out at 2000 baud.
;
; NOTES:
;       During the readin phase, lines without line numbers,
;       rubout characters, and spaces appearing before and
;       immediately after line numbers are filtered out.
;       It is permissible to load tapes which contain line
;       numbers out of sequence or which delete previous
;       lines.
;

        NOLIST

        INCLUDE "HVGLIB.H"      ; HOME VIDEO GAME LIBRARY

;           Defines
HLTPORT EQU     $15             ; KEYPAD COLUMN FOR HALT KEY
;
; SOME CHARACTER EQUATES
NL      EQU     $0D             ; ASCII NEW LINE
RUBOUT  EQU     $1F             ; BASIC 'ERASE' CHARACTER
;
; These equates establish addresses within New BALLY BASIC.
;
HOOKER  EQU     $218B           ; INITIAL HOOK VECTOR VALUES
GL2     EQU     $2C68           ; RET ADDR FOR OUTCH TO SKIP
GL2A    EQU     $2C70           ; ADDR IN INPUT LINE ROUTINE TO SKIP TO
INIT0   EQU     $2531           ; HALT ROUTINE ENTRY
;
; ?? bytes of TAPe input BUFfer [was 48 bytes in Old BALLY BASIC]
BUFSTART EQU    $4280           ; 300 BAUD BUFFER START [screen line 16]
;
; Scratchpad area:
TXTUNF  EQU     $4E20           ; PROGRAM STORAGE AREA POINTER
VARBGN  EQU     $4E22           ; VARIABLE AREA START ADDR
LASTBUF EQU     $4E55           ; LAST BYTE WHICH BUFFER CAN USE
HKVECT  EQU     $4E92           ; HOOK VECTOR AREA START
CHKIO   EQU     $4E98           ; INPUT CHARACTER HOOK VECTOR
OUTCH   EQU     $4E9B           ; OUTPUT CHARACTER HOOK VECTOR
;
; in unused area between BUFFEND and STKLMT
SAVDAT  EQU     $4F26           ; REMEMBERS DATA BENEATH TXTUNF
; [replacement for TAPe INSert pointer, now a full word wide]
POINTER EQU     $4F28           ; 300 BAUD INPUT BUFFER POINTER
TARGET  EQU     $4F2A           ; ADDR TO RELOCATE I/O ROUTINE TO
;
STACK   EQU     $4FEA           ; TOP OF BASIC STACK ZONE [DURAT]
;

; BIT BANGER GOODIES FOLLOW:
; note: New Bally Basic (widely known as Astro Basic)'s Cartridge
; has a built-in 2000 [more likely 1800] baud Tape Interface jack.
; This is accessed by a Read (no Writes allowed!) using 00111100B
; on the upper half of the Address Bus (bits 0 through 9 ignored)
; When READing, the state of Data line D0 follows the tape output.
; To WRITE, Address line 10 is fed to the recorder's mic. input,
; hence the (un-used by this program) BANG1 and BANG0 EQUates :
BANGIN  EQU     $3C00           ; BIT BANGER READ PORT
; BANG1   EQU     $3800           ; BIT BANG CODE TO WRITE A ONE
; BANG0   EQU     $3C00           ; BIT BANG CODE TO WRITE A ZERO
;
; PARAMETERS FOR 300 BAUD BIT DETECTOR
; THESE SPECIFY THE MINIMUM AND MAXIMUM NUMBER
; OF CONSECUTIVE CYCLES OF TONE REQUIRED TO
; RECOGNIZE A ZERO OR A ONE BIT
MIN0    EQU     3
MAX0    EQU     4
MIN1    EQU     6
MAX1    EQU     8
;

        LIST

        ORG     $4000

; :RUN EXECUTION BEGINS HERE
BEGIN:
STARTUP:
        DI                      ; NIX INTERRUPTS
        XOR     A               ; USE OTHER COLOR REGISTERS
        OUT     (HORCB),A
        LD      A,$02           ; GREY SCALE FOREGROUND
        OUT     (COL1R),A
        RLCA
        OUT     (COL2R),A
        LD      A,$07
        OUT     (COL3R),A
        LD      A,$CC
        OUT     (VERBL),A
        LD      HL,BUFSTART     ; RESET 300 BAUD
        LD      (POINTER),HL    ; BUFFER POINTER
; WAIT FOR USER TO SWITCH TAPES
; WHEN DONE USING ORGANISM WILL PRESS 'GO' KEY
REREAD:
CUEW:   IN      A,($17)         ; SENSE 'GO' HEY COL.
        AND     $3F             ; IS GO KEY DOWN?
        JR      NZ,GOTQ                 ; (+$11) YES - WE GOT ONE
        IN      A,(HLTPORT)     ; READ HLT COLUMN
        AND     A               ; CHECK HALT COLUMN
        JP      NZ,TAF          ; IF SO ENDIT
        INC     BC              ; SWEEP BC TO SHOW
        LD      A,B             ; WE ARE WAITING
        RRCA                    ; FOR CUE
        RRCA
        RRCA
        AND     $07             ; SWEEP ONLY
        OUT     (COL0R),A       ; GRAY SCALE
        JR      CUEW                    ; (-$17)

; WE GOT THE CUE
GOTQ:   XOR     A               ; BACK TO
        OUT     (COL0R),A       ; BLACK
; NOW WE WAIT FOR 10 CONSECUTIVE 1 BITS TO APPEAR
; THIS WILL IGNORE ANY GARBAGE APPEARING BEFORE THE
; PROGRAM DATA
WLDR:   LD      L,$0A           ; (RE)SET BIT CTR
WLL:    CALL    GETBIT          ; GET BIT FROM TAPE
        JR      Z,WLDR                  ; (-$07) ZERO-START OVER
        DEC     L               ; ONE-COUNT IT
        JR      NZ,WLL                  ; (-$08) AWAIT QUOTA
; WE NOW FALL INTO THE ...
; AWAIT LINE NUMBER STATE-IGNORE EVERYTHING UNTIL A LINE
; NUMBER APPEARS - THIS WILL DISRREGARD ANY UNNUMBERED
; COMMANDS
; IF AN UNNUMBERED 'RUN' OR
; :RETURN COMMAND IS FOUND WE ENTER
; THE AWAIT NEXT SEGMENT CUE STATE
WLN:    CALL    GETBYTE         ; GET BYTE FROM TAPE
NRET:   CP      ':'             ; HAVE WE GOT A COLON?
        JR      Z,COLN                  ; (+$1a) YEP, TRY FOR :RETURN
        CP      $6A             ; 'RUN' COMMAND?
        JR      Z,REREAD                ; (-$2f) YEP- THEN QUIT
        CALL    TSTNUM          ; IS SHE A NUMBA?
        JR      NC,WLN                  ; (-$10) NO-IGNORE IT
STUF:   CALL    STUFBUF         ; STORE HER AWAY
; WE ARE NO[W] ON A NUMBER
; NOW WE COPY NUMBERS, AND IGNORE SPACES UNTIL A NONSPACE,
; NONNUMERIC IS DETECTED
IGNS:   CALL    GETBYTE         ; FETCH ANOTHER VICTIM
        CALL    TSTNUM          ; TEST FOR NUMERIC
        JR      C,STUF                  ; (-$0b) YEP-KEEP LOOKING
        CP      ' '             ; A SPACE PERHAPS?
        JR      Z,IGNS                  ; (-$0c) IGNORE THE BLANK
        JR      LIN1                    ; (+$11) NONBLANK - LEAVE STATE

; TRY FOR :RETURN STATE - WE CAME HERE AFTER
; READING IN A COLON, SO IF WE GET A 'RETURN'
; WE CAN CEASE LOADING THE SEGMENT
COLN:   CALL    GETBYTE         ; READ ANOTHER BYTE
        CP      ' '             ; ALLOW
        JR      Z,COLN                  ; (-$07) INTERMIXED SPACES
        CP      $70             ; :RETURN TOKEN
        JR      NZ,NRET                 ; (-$29) IF NOT GO BACK
        JP      REREAD          ; YEP-END THIS SEG

; READ LINE STATE
; WE WILL HANG OUT HERE UNTIL A NEW LINE COMES IN
; IN WHICH CASE WE WILL GO BACK TO 'AWAIT LINE NUMBER'
LINL:   CALL    GETBYTE         ; FETCH NEXT BYTE
LIN1:   CP      RUBOUT          ; IF RUBOUT IGNORE IT
        JR      Z,LINL                  ; (-$07)
        CALL    STUFBUF         ; STUFFER IN THE BUFFER
        CP      NL              ; IF NEW LINE
        JR      Z,WLN                   ; (-$3d) WAIT FOR NEXT LINE #
        JR      LINL                    ; (-$10) ELSE GOFOR NEXT CHAR

; ROUTINE TO TEST FOR CHARACTER BEING NUMERIC
TSTNUM: CP      '0'             ; LESS THAN ZERO?
        JR      C,NN                    ; (+$03) NO - JUMP
        CP      '9'+1           ; GREATER THAN NINE?
        RET     C               ; RETURN CY IF NOT
NN:     AND     A               ; CLEAR CY BIT
        RET                     ; TO SAY NOT NUMBER

; ROUTINE TO STORE A CHARACTER INTO THE BUFFER
STUFBUF:
        LD      HL,(POINTER)    ; GET BUFFER POINTER
        LD      (HL),A          ; STUFF CHAR WITHIN
        INC     HL              ; BUMP POINTER
        LD      (POINTER),HL    ; AND SAVE
        RET                     ; AND GO HOME

; GET A BYTE FROM AUDIO TAPE ROUTINE
GETBYTE:
        CALL    GET0            ; GET A START BIT
        JR      NZ,GETBYTE              ; (-$05) WAIT FOR IT
        LD      HL,$0800        ; INIT BIT CTR AND ACCUM
BYTL:   CALL    GETBIT          ; FETCH A BIT
        OR      L               ; OR IN DATA SO FAR
        RRCA                    ; SHIFT OVER
        LD      L,A             ; AND SAVE
        DEC     H               ; DCR BIT COUNTER
        JR      NZ,BYTL                 ; (-$09) FILL OUT BYTE
        RET

 ; GET BIT ROUTINE
 ;
 ; THIS ROUTINE INPUTS A BIT IN 300 BAUD FORMAT
 ; USING THE BUILT-IN AUDIO INTERFACE CIRCUIT
 ; IT DOES THIS BY MEASURING THE FREQUENCY
 ; OF THE INPUT SQUARE WAVES.
 ; AS 8 CONSECUTIVE SHORT SQUARE WAVES DENOTES A ONE BIT
 ; AND 4 CONSECUTIVE LONG WAVES DENOTES A ZERO BIT
 ; WE MAINTAIN COUNTERS FOR EACH TYPE, AND RETURN
 ; ONE OR ZERO WHEN ENOUGH CYCLES ARE COUNTED
 ;
 ; THE ENTRY 'GET0' IS ENTERED WHEN A START BIT IS
 ; SOUGHT. 'GET0' INSISTS ON RECIEVING A FULL LENGTH
 ; ZERO WAVE
GET0:   LD      C,$00           ; SYNC ON START BIT
NEXW:   LD      E,$00           ; RESET BIT LENGTH TIMER
        IN      A,(HLTPORT)     ; SENSE HALT COLUMN
        AND     A               ; IF ANY DOWN
        JP      NZ,TAF          ; KICKOUT
        LD      A,(BANGIN)      ; GET TAPE DATA
        LD      D,A             ; STUFF IN TRACKER
G0L:    LD      A,(BANGIN)      ; SENSE IT AGAIN
        XOR     D               ; ANY TRANSITION?
        RRCA
        JR      C,GOTT                  ; (+$05) JUMP IF SO
        INC     E               ; COUNT TIME
        JR      NZ,G0L                  ; (-$0a) TIMEOUT COND?
        JR      GET0                    ; (-$1a) YEP - START OVER

GOTT:   LD      A,D             ; LAST TIME TO ACC
        LD      D,E             ; SET NEW LAST TIME
        ADD     A,E             ; SUM LAST AND NOW   [was non-standard  ADD E]
        CP      $0F             ; GOOD ENOUGH?
        JR      C,NEXW                  ; (-$1f) NO-KEEP LOOKIN
        LD      BC,$0001        ; YEP-COUNT THAT ZERO
        JR      GBNEXT                  ; (+$09) AND JOIN GETBIT

; THIS ENTRY IMPOSES NO SPECIAL CRITERIA
; AND IS ENTERED FROM LEADER WAIT AND TO GET
; CHARACTER DATA BITS
; B=ONE COUNTER, C=ZERO COUNTER
GETBIT:
        LD      BC,$0000        ; RESET BIT COUNTERS
        IN      A,(HLTPORT)     ; ANOTHER HALT COL
        AND     A               ; CHECK
        JP      NZ,TAF
GBNEXT:
        LD      E,$00           ; RESET BIT TIMER
        LD      A,(BANGIN)      ; SAMPLE TAPE DATA
        LD      D,A             ; SAVE IN TRACKER
TIME:   LD      A,(BANGIN)      ; SAMPLE AGAIN
        XOR     D               ; REVEAL TRANSITION
        RRCA                    ; IF WE GOT ONE
        JR      C,TRAN                  ; (+$05) JUMP OUT
        INC     E               ; COUNT TIME
        JR      NZ,TIME                 ; (-$0a) TIMEOUT CHECK
        JR      GETBIT                  ; (-$1b) TIMEOUT - START OVER

; WE HAVE ONE HALF CYCLE-SO WE GO FOR THE OTHER HALF
; SAME LOGIC AS ABOVE CODE
TRAN:
        LD      A,(BANGIN)
        XOR     D
        RRCA
        JR      NC,GOTB                 ; (+$05)
        INC     E
        JR      NZ,TRAN                 ; (-$0a)
; TIM0:
        JR      GETBIT                  ; (-$27) WE HAVE TIMED OUT

; WE HAVE A FULL WAVE TIME - WE WILL
; CLASSIFY IT AND INCREMENT THE APPROPRIATE BIT
; COUNTER IF THE 'OTHER' BIT COUNTER MEETS
; MINIMUM CRITERION WE WILL RETURN THE 'OTHER' BIT
; VALUE, ELSE IF THE 'NOW' BIT COUNTER IS HIGH
; ENOUGH WE WILL RETURN THE 'NOW' BIT
; IF NEITHER ARE LARGE ENOUGH WE WILL KEEP SAMPLING
GOTB:   LD      A,E
        CP      $0C             ; WHICH HAVE WE?
        JR      C,TRY1                  ; (+$0d) JUMP IF ONE
TRY0:   INC     C               ; COUNT THE ZERO
        LD      A,B             ; ENOUGH ONES?
        CP      MIN1
        JR      NC,RET1                 ; (+$12) YES - RETURN 1 BIT
        LD      A,C             ; AT MAX ZEROS?
        CP      MAX0
        JR      C,GBNEXT               ; (-$2e) NO - GET MORE CYCLES
RET0:   XOR     A               ; RETURN A ZERO BIT
        RET

TRY1:   INC     B               ; COUNT A ONE BIT
        LD      A,C             ; ENOUGH ZERO BITS?
        CP      MIN0
        JR      NC,RET0                 ; (-$08) YEP - GO TO ZERO RETURN
        LD      A,B             ; MAX ONE BITS?
        CP      MAX1
        JR      C,GBNEXT                ; (-$3b) YEP
RET1:   XOR     A
        INC     A
        RET

; THIS SEQUENCE IS ENTERED AFTER THE USING ORGANISM
; PRESSES A KEY IN THE HALT COLUMN
; IF THE KEY WAS NOT THE HALT KEY WE GO BACK FOR AN
; ADDITIONAL SEGMENT. IF IT WAS HALT WE CLOSE THE BUFFER
; AND THEN RELOCATE THE BUFFER TO THE HIGHEST POSSIBLE
; ADDRESS, ESTABLISH THE SPECIAL I/O ROUTINES IN
; THE BASIC STACK ZONE, AND MODIFY THE HOOK VECTORS
; POINT AT THEM
; WE THEN CALL BASIC TO CONVERT THE BUFFER
TAF:
        LD      SP,STACK        ; RESET THE STACK POINTER
        RRCA                    ; WAS THAT A HALT?
        JP      NC,REREAD       ; NO - GO BACK FOR NEXT SEGMENT
        XOR     A               ; DENOTE OUT OF HALT
        OUT     (COL0R),A
        LD      HL,LASTLINE     ; CLOSE THE BUFFER WITH
        LD      DE,(POINTER)    ; NL,PRINT,NL,$FF
        LD      BC,EOLL-LASTLINE+1
        LDIR
        EX      DE,HL           ; HL = POINTER
; MOVE BUFFER UP TO THE HIGHEST POSSIBLE ADDRESSES
        LD      DE,LASTBUF+1
CPYL:   DEC     HL              ; DECREMENT POINTERS
        DEC     DE
        LD      A,(HL)          ; FETCH SOURCE
        LD      (HL),$00        ; CLEAR SOURCE
        LD      (DE),A          ; STORE AT DEST
        LD      A,H             ; BACK AT START?
        CP      BUFSTART >> 8
        JR      NZ,CPYL                 ; (-$0b) LOOP BACK
        LD      A,L
        CP      BUFSTART & $FF
        JR      NZ,CPYL                 ; (-$10) IF NOT YET
        LD      (POINTER),DE    ; SAVE CORRECTED PTR
        LD      HL,(TXTUNF)     ; REMEMBER DATA BENEATH
        LD      (SAVDAT),HL     ; TXTUNF
        LD      HL,$5555        ; INITIALIZE PROGRAM
        LD      ($4002),HL      ; STORAGE AREA
        LD      HL,$A004        ; AND TXTUNF
        LD      (TXTUNF),HL
        LD      HL,TARGET       ; PLUG HOOK VECTORS
        LD      (CHKIO+1),HL    ; WITH SPECIAL I/O
        INC     HL              ; ROUTINES
        INC     HL
        LD      (OUTCH+1),HL
; MOVE THE SPECIAL I/O ROUTINES
; INTO BASIC STACK AREA
        LD      HL,CODS
        LD      DE,TARGET
        LD      BC,ENDPRG-CODS
        LDIR
        JP      INIT0           ; ENTER BASIC

; THIS INFORMATION IS APPENDED TO THE TAPE BUFFER
; TO CLOSE IT OFF. IT WILL CLEAR THE SCREEN AFTER
; THE CONVERSION PROCESS IS COMPLETE
LASTLINE:
        DB      NL
        DB      $69             ; TOKEN CODE FOR 'CLEAR'
        DB      NL
        DB      $FF             ; LIST TERMINATOR
EOLL:
CODS:
        JR     LCHKIO

; SPECIAL OUTPUT CHARACTER ROUTINE
; IT REFUSES TO DO ANY PRINTING
; IT DOES CHECK TO SEE WHERE IT WAS CALLED FROM
; IF IT WOULD GO BACK TO GL2 IN
; GLED WE WILL SKIP SEVERAL UGLY INSTRUCTIONS
; WHICH WOULD PUT UP A CURSOR
        EX      (SP),HL         ; HL=RETURN ADDR
        PUSH    AF              ; SAVE A
        LD      A,H             ; CHECK FOR CALL
        CP      GL2 >> 8        ; FROM GL2
        JR      NZ,OK                   ; (+$0d)
        LD      A,L
        CP      GL2 & $FF
        JR      NZ,OK                   ; (+$08)
; WE WERE CALLED FROM GL2, SO SHUFFLE STACK AND
; GO BACK AT GL2A
        POP     AF
        POP     HL
        PUSH    BC
        PUSH    HL
        PUSH    DE
        JP      GL2A

; CALL FROM ELSEWHERE - JUST GO HOME
OK:     POP     AF
        EX      (SP),HL
        RET

; GET CHARACTER ROUTINE - FETCHES CHARACTER
; FROM 300 BAUD BUFFER
; WE STORE THE DATA BENEATH TXTUNF JUST IN
; CASE OU[R] POINTER POINTS THERE
LCHKIO:
        LD      HL,(TXTUNF)     ; SAVE CURRENT TXTUNF
        PUSH    HL
        LD      HL,(SAVDAT)     ; GET BUFFER DATA
        LD      (TXTUNF),HL     ; AND FUDGE
        LD      HL,(POINTER)    ; GET BUFFER PTR
        LD      A,(HL)          ; AND CHARACTER
        LD      (HL),$00        ; CLEAR CHARACTER
        INC     HL              ; BUMP PTR
        LD      (POINTER),HL    ; SAVE PTR
        LD      HL,(TXTUNF)     ; SAVE BUFFER DATA
        LD      (SAVDAT),HL     ; AS MAY BE ZEROED
        POP     HL              ; RESTORE TXTUNF
        LD      (TXTUNF),HL
        INC     A               ; END OF LIST?
        JR      Z,GEOF                  ; (+$02) YEP JUMP
        DEC     A               ; NO - FIXIT
        RET                     ; AND GO BACK

; WE ARE DONE - RESET VARIABLES TO ZERO
; ZERO A-Z
GEOF:   SYSSUK  FILL            ; UPI FILL memory with data
        DW      VARBGN          ; ... Memory Address = 20002 ($4E22)
        DW      $0034           ; ... Byte Count = 52
        DB      $00             ; ... Data = 0
        ;
; RESET HOOK VECTOR
        SYSSUK  MOVE            ; UPI MOVE block transfer
        DW      HKVECT          ; ... Destination Address = 20114 ($4E92)
        DW      $000E           ; ... Byte Count = 14
        DW      HOOKER          ; ... Source Address = 8587 ($218B)
        ;
        LD      A,$B0           ; RESET VERTICAL
        OUT     (VERBL),A       ; BLANK PORT
        LD      A,$2C           ; ADD HORIZONTAL
        OUT     (HORCB),A       ; COLOR BOUNDARY
        JP      INIT0           ; HALT BASIC
ENDPRG:

        END

; Comment Section [down past END, needs no ';'s]

300 To 2000 BAUD LOADER PROGRAM
(C) 1981 Jay Fenton for Astrovision Inc.
----------------------------------------

NOTE: To assemble this program header file named HVGLIB
      is required.

This program is for the Bally Astrocade game console and
the AstroBASIC cartridge.


End Comments - Changes/Updates (By Adam Trionfo)
------------------------------

Version 1.0 (Dec. 16, 2007)

   - Program first re-typed from source-code

   - All program lines correspond to the original program.

   - All non-standard Z-80 Mnemonics have been changed to
      standard Z-80 Mnemonics.

   - There is an assembler warning for line 247 (LD  D,E).
     This line still assembles to $53 (which it is supposed
     to).  I'm not sure why Zmac is giving this error.

   - Checked, by hand, that this program assembles and
     matches, byte-for-byte with the listing by Jay Fenton.


; Version 1.2 - Standardized by Richard C. Degler
; Source code re-listing of the file "300BLOAD.asm"
;
; CPU Type: Z80 - loads with ASTRO Basic ONLY!
;
; Created with dZ80 2.0 using script "BallyHVG.LUA"
;
; on Wednesday, 23 of February 2011 at 02:56 AM
;
; This code can be assembled into a usable binary using the
; ZMac assembler using command line "zmac -i -m 300BLOAD.asm"
;
 - Sorted the EQUates and added note to "Bit Banger Goodies".

 - Used only $xx for code instead of mix of 0xxH and decimal.

 - Wow, Adam - you translated this from TDL's 8080 mnemomics!

 - Assembler's "non-standard syntax" warning was for "ADD  E"
   on old line 248 (not sure why the previous line was flagged)

 - Corrected two very mino[r] typos in transcribed comments.

 - Actually assembled this and compared it to earlier versions.

more note: This program uses the entire screen (past its area)
as a huge Tape Buffer (instead of having a small Ring Buffer),
only saving lines that are numbered.  Since 300-baud's direct
commands (NLN) and .REMarks might have a few numbers in them,
these should be edited from the recording if at all possible.

; ***** End of Comments *****
