back to project page

Apple II Programmers Aid 1.3.$D4D5~$D52D - Relocater.BIN Disassembly

                   ; ==============================================================================
                   ; Apple II [$D0 ROM] (341-0016) - Programmer's Aid #1 [1978]
                   ; ------------------------------------------------------------------------------
                   ; Part 3 [$D4D5~$D52D]: 6502 Relocation Subroutine 
                   ; by Steve Wozniak [WOZ], 1977-11-10;
                   ; 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/07]
                   ; ==============================================================================
                   ; 
                   ; ==============================================================================
                   ; Relocater Routine Equates:
                   ; ==============================================================================
                   ; 
                   R1L             EQU   $02    {addr/1} ;Sweet 16 Register #1
                   INST            EQU   $0B    {addr/3} ;3-Byte Instuction Field
                   LENGTH          EQU   $2F    {addr/1} ;Disassembler Instruction Display Length
                   YSAV            EQU   $34    {addr/1} ;Y-Reg Safe for Monitor Command Processing
                   A1L             EQU   $3C    {addr/1} ;Monitor General Purpose A1-Reg, Low
                   A4L             EQU   $42    {addr/1} ;Monitor General Purpose A4-Reg, Low
                   INBUFF          EQU   $0200           ;Apple II Input Buffer, Start of (~1 Page)
                   SETUSRADR       EQU   $D5B0           ;Sets Monitor User Command (Ctrl-Y) Vector
                   SW16            EQU   $F689           ;Sweet 16 Interpreter (Op-Codes follow it)
                   INSDS2          EQU   $F88E           ;Monitor Disassembler Entry Point
                   NXTA4           EQU   $FCB4           ;Subroutine to Increment Mon A4 Register

                                   ORG   $D4D5
                   ; 
                   ; ==============================================================================
                   ; Relocater Routines:
                   ; ==============================================================================
                   ; Set Monitor User Command (Ctrl-Y) Vector to Relocater Routine Location:
                   ; ------------------------------------------------------------------------------
                   ; 
                   ; ----------------------------------- ;Setup Mon User Cmd (Ctrl-Y) Location:
D4D5: A9 DC        SETRLCYV        LDA   #<RELOC         ;Get Relocater Routine Address, Low
D4D7: A0 D4                        LDY   #>RELOC         ;Get Relocater Routine Address, High
D4D9: 4C B0 D5                     JMP   SETUSRADR       ;Setup Mon User Cmd (Ctrl-Y) Vector

                   ; ==============================================================================
                   ; Monitor User Command (Ctrl-Y) Vector Setup Routine:
                   ; ==============================================================================
                   ; Shared by: Relocater, Tape Verify, & RAM Test Routines;
                   ; Located further below, between the Tape Verify & RAM Test Routines:
                   ; ------------------------------------------------------------------------------
                   ;                            ORG  $D5B0
                   ; ----------------------------------------- ;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
                   ; ==============================================================================
                   ; 
                   ; 
                   ; ==============================================================================
                   ; 6502 Relocation Subroutine [For use via Apple II Monitor (at Star {*} Prompt)]
                   ; ==============================================================================
                   ; 1. Define Blocks:        *A4<A1.A2 ^Y  (^Y is Ctrl-Y)
                   ; ------------------------------------------------------------------------------
                   ; 2. First Segment:        *A4<A1.A2 ^Y  (If Code)
                   ;                          *A4<A1.A2M    (If Move)
                   ; ------------------------------------------------------------------------------
                   ; 3. Subsequent Segments:  *.A2 ^Y       (If Code)
                   ;                          *.A2M         (If Move)
                   ; ==============================================================================
                   ; 
D4DC: A4 34        RELOC           LDY   YSAV            ;Get Monitor Command Processing Pointer
D4DE: B9 00 02                     LDA   INBUFF,Y        ;Get Monitor Command from Input Buffer
D4E1: C9 AA                        CMP   #'*' | $80      ;Assure we are at the Monitor Prompt
D4E3: D0 0C                        BNE   RELOC2          ;Branch if Not at the Monitor Prompt
                   ;                                     ;Else, Initialize Relocation Pointers:
D4E5: E6 34                        INC   YSAV            ;Advance Command Processing Pointer
D4E7: A2 07                        LDX   #7              ;Prepare to Copy 8 Bytes ...
D4E9: B5 3C        INIT            LDA   A1L,X           ;From: Monitor General Purpose Registers
D4EB: 95 02                        STA   R1L,X           ;To: Sweet 16 Interpreter (ZP) Registers
D4ED: CA                           DEX                   ;Reduce Byte-Count Index-Pointer 
D4EE: 10 F9                        BPL   INIT            ;Loop until all Bytes have been Copied
D4F0: 60                           RTS                   ;Then Return to Caller

D4F1: A0 02        RELOC2          LDY   #2              ;Prepare to Copy 3 Bytes ...
D4F3: B1 3C        GETINS          LDA   (A1L),Y         ;From: A1 Address Pointer [(Indirect),Y]
D4F5: 99 0B 00                     STA   INST,Y          ;To: 3-Byte Instuction Field [Abs,Y]
D4F8: 88                           DEY                   ;Reduce Byte-Count Index-Pointer 
D4F9: 10 F8                        BPL   GETINS          ;Loop until all Bytes have been Copied
                   ;                                     ;Compute Instruction Length from Op-Code:
D4FB: 20 8E F8                     JSR   INSDS2          ;Monitor Disassembler Entry Point
D4FE: A6 2F                        LDX   LENGTH          ;Disassembler Instruction Display Length
                   ;                                     ;^[Sets X=# of Bytes: 1, 2, or 3]
D500: CA                           DEX                   ;Reduce Byte-Count Index-Pointer 
                   ;                                     ;^[Now, # of Bytes is X+1: X= 0, 1, or 2]
D501: D0 0C                        BNE   TRANSLATE       ;If Not Zero, Interpret Sweet 16 Op-Codes
D503: A5 0B                        LDA   INST            ;Get Instuction from 3-Byte Field
D505: 29 0D                        AND   #%00001101      ;Weed Out Non-Zero-Page ...
D507: F0 14                        BEQ   STINST          ; 2-Byte Immediate Operations
D509: 29 08                        AND   #%00001000      ;If Zero-Page Address, ...
D50B: D0 10                        BNE   STINST          ; Then Clear High Byte
D50D: 85 0D                        STA   INST+2          ;3-Byte Instuction Field
D50F: 20 89 F6     TRANSLATE       JSR   SW16            ;Sweet 16 Interpreter (Op-Codes follow)...
                   ; ==============================================================================
                   ; *** SourceGen needs a way to interpret Sweet 16 Operations like the following:
                   ; [See: "SWEET16: The 6502 Dream Machine"; BYTE Magazine, Nov 1977, Pgs 150~159]
                   ; [And: "Apple II Reference Manual (Red Book)"; §C6 Sweet 16 Listing, Pgs 96~99]
                   ; ==============================================================================
                   ; Sweet 16 Equates: Zero-Page Locations used here for Sweet 16 Interpreter Op's
                   ; ==============================================================================
                   ; FRMBEG     EQU    $01    {addr/1}   ;SW16/R0H: Beginning of Source Block
                   ; FRMEND     EQU    $02    {addr/2}   ;SW16/R1L: End of Source Block {Low/High}*
                   ; TOBEG      EQU    $04    {addr/2}   ;SW16/R2L: Beginning of Destination Block*
                   ; ADR        EQU    $06    {addr/2}   ;SW16/R3L: Address Part of Instuction
                   ; ==============================================================================
                   ; TRANSLATE  JSR    SW16              ;Sweet 16 Interpreter (Op-Codes follow)...
                   ; ^ XLATE ^  ------------------------------------- ;If Address of Zero Page
D512: 22                           DFB   $22             ;LD   FRMEND ;or Absolute Address is in
D513: D6                           DFB   $D6             ;CPR  ADR    ;Source (FRM) Block then
D514: 02 06                        DDB   $0206           ;BNC  SW16RT ;Substitute:
D516: 26                           DFB   $26             ;LD   ADR    ;(Address Part of Instuction)
D517: B1                           DFB   $B1             ;SUB  FRMBEG ;-(Source Start Address)
D518: 02 02                        DDB   $0202           ;BNC  SW16RT ;[Exit: Branch if No Carry]
D51A: A4                           DFB   $A4             ;ADD  TOBEG  ;+(Destination Start Address)
D51B: 36                           DFB   $36             ;ST   ADR    ;(Address Part of Instuction)
D51C: 00           :SW16RT         DFB   $00             ;RTN         ;[Return to 6502 Mode]

                   ; ==============================================================================
                   ; 
D51D: A2 00        STINST          LDX   #0              ;Clear X-Index; Prep to Copy LENGTH Bytes
D51F: B5 0B        STINS2          LDA   INST,X          ;From: 3-Byte Instuction Field [Abs,X]
D521: 91 42                        STA   (A4L),Y         ;To: A4 Address Pointer [(Indirect),Y]
D523: E8                           INX                   ;Advance X-Index
D524: 20 B4 FC                     JSR   NXTA4           ;Subroutine to Increment Mon A4 Register
D527: C6 2F                        DEC   LENGTH          ;Disassembler Instruction Display Length
D529: 10 F4                        BPL   STINS2          ;Loop until all Bytes have been Copied
D52B: 90 C4                        BCC   RELOC2          ;Loop until Relocation is Finished
D52D: 60                           RTS                   ;Return to Caller

Symbol Table

GETINS$D4F3
INIT$D4E9
RELOC$D4DC
RELOC2$D4F1
SETRLCYV$D4D5
STINS2$D51F
STINST$D51D
TRANSLATE$D50F