back to project page

Apple II Programmers Aid 1.4.$D52E~$D5BB - Tape Verify.BIN Disassembly

                   ; ==============================================================================
                   ; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
                   ; ------------------------------------------------------------------------------
                   ; Part 4 [$D52E~$D5BB]: Tape Verify Routine by Steve Wozniak [WOZ], 1978-01;
                   ; Copyright (c) 1978 by Apple Computer Inc.  All Rights Reserved
                   ; ------------------------------------------------------------------------------
                   ; Instructions are in the Programmer's Aid #1 Installation and Operating Manual
                   ; ==============================================================================
                   ; Analyzed (via McFadden's SourceGen) by James Davis  [Last Updated: 2020/06/10]
                   ; ==============================================================================
                   ; 
                   ; Tape Verify Routine Equates:
                   ; 
                   CHKSUM          EQU   $2E    {addr/1} ;Tape Input Accumulated Checksum
                   A1              EQU   $3C    {addr/2} ;Monitor General Purpose A1-Register
                   HIMEM           EQU   $4C    {addr/2} ;Integer BASIC: HIMEM Address Pointer
                   PP              EQU   $CA    {addr/2} ;Integer BASIC: Start of Program Pointer
                   PRLEN           EQU   $CE    {addr/2} ;Integer BASIC: Program Length
                   XSAVE           EQU   $D8    {addr/1} ;Integer BASIC: X-Index Register Safe
                   USRADR          EQU   $03F8  {addr/3} ;Monitor User Command (Ctrl-Y) Vector
                   HDRSET          EQU   $F11E           ;BASIC S/R: Sets Tape Pointers to $CE,$CF
                   PRGSET          EQU   $F12C           ;BASIC S/R: Sets Tape Pointers for Program
                   NXTA1           EQU   $FCBA           ;Monitor Routine to INC (A1) then CMP (A2)
                   HEADR           EQU   $FCC9           ;Monitor Write Tape Sync Header Routine
                   RDBYTE          EQU   $FCEC           ;Monitor Tape READ Routine (1-Byte|8-Bits)
                   RD2BIT          EQU   $FCFA           ;Monitor Tape READ Routine (2 Transitions)
                   RDBIT           EQU   $FCFD           ;Monitor Tape READ Routine (1 Transition)
                   PRA1            EQU   $FD92           ;Print CR, Hex of (A1), then Minus Sign
                   PRBYTE          EQU   $FDDA           ;Print A-Reg as Two-Digit Hex Number
                   COUT            EQU   $FDED           ;Print A-Reg to Output Device
                   FINISH          EQU   $FF26           ;Check Accumulated Checksum & Ring Bell
                   PRERR           EQU   $FF2D           ;Print "ERR" & Sound Bell (Beep)

                                   ORG   $D52E
                   ; 
                   ; ==============================================================================
                   ; Tape Verify Routines:
                   ; ==============================================================================
                   ; Set Monitor User Command (Ctrl-Y) Vector to Tape Verify Routine Location:
                   ; ------------------------------------------------------------------------------
                   ; 
                   ; ----------------------------------- ;Monitor Verify S/R Entry Pt.: D52EG <Rtn>
                   ;                                     ;(to verify Mem-Range just saved on Tape)
                   ; 
                   ; ----------------------------------- ;Setup Mon User Cmd (Ctrl-Y) Location:
D52E: A9 54        SETTVCYV        LDA   #<TAPEVFY       ;Get Tape Verify Routine Address, Low
D530: A0 D5                        LDY   #>TAPEVFY       ;Get Tape Verify Routine Address, High
D532: 4C B0 D5                     JMP   SETUSRADR       ;Setup Mon User Cmd (Ctrl-Y) Vector

                   ; ==============================================================================
                   ; Tape Verify BASIC Routine:
                   ; ==============================================================================
                   ; 
                   ; ----------------------------------- ;BASIC Verify S/R Entry Pt.: Call -10955
                   ;                                     ;(to verify a program just saved on Tape)
D535: 86 D8        VFYBSC          STX   XSAVE           ;Preserve X-Index Register for BASIC
                   ;                                     ;Calculate Program Length, Put into PRLEN:
D537: 38                           SEC                   ;Prep for Subtract w/o Borrow [A-Data-!C]
D538: A2 FF                        LDX   #$FF            ;Prep X-Index: Adrs+1, X=255=-1 & X=256=0
D53A: B5 4D        GETLEN          LDA   HIMEM+1,X       ;GET HIMEM Address, Low 1st & High 2nd It
D53C: F5 CB                        SBC   PP+1,X          ;Subtract Program Start Address, Low/High
D53E: 95 CF                        STA   PRLEN+1,X       ;Set Program Length, Low 1st & High 2nd
D540: E8                           INX                   ;Advance X-Index: X=255=-1 -> X=256=0
D541: F0 F7                        BEQ   GETLEN          ;Loop to Do High Addresses, 2nd Iteration
D543: 20 1E F1                     JSR   HDRSET          ;Set Tape Pointers to ...
D546: 20 54 D5                     JSR   TAPEVFY         ;Verify Header on Tape
D549: A2 01                        LDX   #1              ;Prep for PRGSET
D54B: 20 2C F1                     JSR   PRGSET          ;Set Tape Pointers to ...
D54E: 20 54 D5                     JSR   TAPEVFY         ;Verify Program on Tape
D551: A6 D8                        LDX   XSAVE           ;Restore X-Reg for BASIC
D553: 60                           RTS                   ;Return to Caller

                   ; ==============================================================================
                   ; Tape Verify RAM Image (A1,A2):
                   ; ==============================================================================
                   ; 
D554: 20 FA FC     TAPEVFY         JSR   RD2BIT          ;Monitor Tape READ Routine (2 Transitions)
D557: A9 16                        LDA   #$16            ;Set Synchronization Header Length
D559: 20 C9 FC                     JSR   HEADR           ;Synchronize on Tape Header
D55C: 85 2E                        STA   CHKSUM          ;Initialize Tape Accumulated Checksum
D55E: 20 FA FC                     JSR   RD2BIT          ;Monitor Tape READ Routine (2 Transitions)
                   ; ----------------------------------- ;Read a Bit from Tape (Loop):
D561: A0 24        VRFY2           LDY   #$24            ;Set Count for RD2BIT/RDBIT Sampling
                   ;                                     ;^[Gets Reduced Until Voltage Transitions]
                   ;                                     ;^[(Used to Set Carry Flag for a One-Bit)]
D563: 20 FD FC                     JSR   RDBIT           ;Monitor Tape READ Routine (1 Transition)
D566: B0 F9                        BCS   VRFY2           ;Loop if RD2BIT/RDBIT Read a One-Bit
D568: 20 FD FC                     JSR   RDBIT           ;Monitor Tape READ Routine (1 Transition)
D56B: A0 3B                        LDY   #$3B            ;Set Count for RD2BIT/RDBIT Sampling
                   ;                                     ;^[Gets Reduced Until Voltage Transitions]
                   ;                                     ;^[2 Transitions/Bit; 16 Transitions/Byte]
                   ; ----------------------------------- ;Read a Byte from Tape (Loop):
D56D: 20 EC FC     VRFY3           JSR   RDBYTE          ;Monitor Tape READ Routine (1-Byte|8-Bits)
D570: F0 0E                        BEQ   EXTDEL          ;RDBYTE Returns (X=0)->(Z=1); Always Taken
                   ; 
                   ; ----------------------------------- ;Accumulator contains Byte Read from Tape
D572: 45 2E        VFYLOOP         EOR   CHKSUM          ;Update Tape Accumulated Checksum
D574: 85 2E                        STA   CHKSUM          ;Set New Tape Accumulated Checksum
D576: 20 BA FC                     JSR   NXTA1           ;Increment A1; Sets Carry Flag if A1>A2
D579: A0 34                        LDY   #$34            ;Set Count for RD2BIT/RDBIT Sampling
                   ;                                     ;^[Gets Reduced Until Voltage Transitions]
                   ;                                     ;^[2 Transitions/Bit; 16 Transitions/Byte]
                   ;                                     ;^[One < used in Read for an Extra 12 (?)]
D57B: 90 F0                        BCC   VRFY3           ;Loop Until A1>A2
D57D: 4C 26 FF                     JMP   FINISH          ;Verify Checksum & Beep; Returns to Caller

                   ; ----------------------------------- ;Extra Delay to Equalize Timing:
D580: EA           EXTDEL          NOP                   ;Delay 2 Machine Cycles
D581: EA                           NOP                   ;Delay 2 Machine Cycles More
D582: EA                           NOP                   ;Delay 2 Machine Cycles (+12 usec total)
                   ; ----------------------------------- ;Accumulator contains Byte Read from Tape
D583: C1 3C                        CMP   (A1,X)          ;Is Byte in Mem Same as Byte from Tape?
D585: F0 EB                        BEQ   VFYLOOP         ;Loop if Bytes Match
                   ; =================================== ;Else, Handle Error:
D587: 48                           PHA                   ;Push/Save Wrong Byte from Tape
D588: 20 2D FF                     JSR   PRERR           ;Print "ERR" & Sound Bell (Beep)
D58B: 20 92 FD                     JSR   PRA1            ;Print CR, (A1:Address), then Minus Sign
D58E: B1 3C                        LDA   (A1),Y          ;Get Byte from Memory at (A1:Address),Y=0
D590: 20 DA FD                     JSR   PRBYTE          ;Print A-Reg as Two-Digit Hex Number
D593: A9 A0                        LDA   #' ' | $80      ;Get a Blank/Space Character
D595: 20 ED FD                     JSR   COUT            ;Print A-Reg to Output Device
D598: A9 A8                        LDA   #'(' | $80      ;Get an Open-Parenthesis Character
D59A: 20 ED FD                     JSR   COUT            ;Print A-Reg to Output Device
D59D: 68                           PLA                   ;Pull/Retrieve Bad Byte Saved from Tape
D59E: 20 DA FD                     JSR   PRBYTE          ;Print A-Reg as Two-Digit Hex Number
D5A1: A9 A9                        LDA   #')' | $80      ;Get a Close-Parenthesis Character
D5A3: 20 ED FD                     JSR   COUT            ;Print A-Reg to Output Device
D5A6: A9 8D                        LDA   #$8D            ;Get High ASCII Ctrl-M: Carriage Return
D5A8: 4C ED FD                     JMP   COUT            ;Print A-Reg to Output; Returns to Caller

                   ; =================================== ;Extra Repeated Code (Unused/Filler):
D5AB: A9 8D        XCROUT          LDA   #$8D            ;Get High ASCII Ctrl-M: Carriage Return
D5AD: 4C ED FD                     JMP   COUT            ;Print A-Reg to Output; Returns to Caller

                   ; ==============================================================================
                   ; Monitor User Command (Ctrl-Y) Vector Setup Routine:
                   ; ==============================================================================
                   ; Shared by: Tape Verify, Relocater, & RAM Test Routines
                   ; ------------------------------------------------------------------------------
                   ; 
                   ; ----------------------------------- ;Setup Mon User Cmd (Ctrl-Y) Vector:
D5B0: 8D F9 03     SETUSRADR       STA   USRADR+1        ;Preset User Address, Low
D5B3: 8C FA 03                     STY   USRADR+2        ;Preset User Address, High
D5B6: A9 4C                        LDA   #$4C            ;Get JMP OpCode
D5B8: 8D F8 03                     STA   USRADR          ;Preset to JMP OpCode
D5BB: 60                           RTS                   ;Return to Caller

Symbol Table

EXTDEL$D580
GETLEN$D53A
SETTVCYV$D52E
SETUSRADR$D5B0
TAPEVFY$D554
VFYBSC$D535
VFYLOOP$D572
VRFY2$D561
VRFY3$D56D
XCROUT$D5AB