assembly6502ca65apple-ii

6502 ASM linker calculates wrong jump offset


It seems to me that 6502's ASM linker screws the logical sequence of my code that way so I can't explain why. At the lines marked with ( <-- O) the address pointer becoming offset by 2 bytes. So it jumps at the line marked with ( <-- 1). Then, every data pointer at the lines marked with ( <-- S) has starting address offset in 4 bytes. As the result, part of a message is not being displayed.

Please share with me your thoughts of what I possibly doing wrong here.

main.asm

.org $2000

.macro  asc Arg
        .repeat .strlen(Arg), I
        .byte   .strat(Arg, I) | $80
        .endrep
.endmacro

.define asc2(Arg)  asc Arg

.macro  ascz Arg
        .repeat .strlen(Arg), I
        .byte   .strat(Arg, I) | $80
        .endrep
        .byte   $00
.endmacro

.macro  asccr Arg
        .repeat .strlen(Arg), I
        .byte   .strat(Arg, I) | $80
        .endrep
        .byte   $8d
.endmacro

    COUT     = $FDED
    CHR_CR = $8D
    PTR = $06
    VTAB    = $FC22
    CH  = $24
    CV  = $25

    cld
    ldx #$FF
    txs
    lda #$69
    sta $03F2
    lda #$ff
    sta $03F3
    eor #$a5
    sta $03F4
    jsr $FC58
    jsr $FE84
    jsr $FE89
    jsr $FE93

    lda $BF98
    and #$A8
    cmp #$A8
    bcs @ErrEnvMachine
    clc
    lda #$02
    bit $BF98
    beq @ErrEnv80Col

@ErrEnvMachine:
    lda #$01
    jmp ERRHNDLR
@ErrEnv80Col:
    lda #$02
    jmp ERRHNDLR

ERRHNDLR:
    cmp #$01
    beq @ErrEnvMachine
    cmp #$02
    beq @ErrEnv80Col
    bne @ErrGeneric

@ErrEnvMachine:
    lda #<MErrEnvM
    sta PTR
    lda #>MErrEnvM
    sta PTR+1
    beq PrintErrMsg

@ErrEnv80Col:
    lda #<MErr80Col
    sta PTR
    lda #>MErr80Col
    sta PTR+1
    beq PrintErrMsg

@ErrGeneric:
    lda #<MErrgen
    sta PTR
    lda #>MErrgen
    sta PTR+1
PrintErrMsg:
    ldx #$0
    ldy #$17
    jsr GOTOXY
    ldy #$00
:   lda (PTR),y
    beq :+
    jsr COUT
    iny
    bne :-
:   jmp EXIT

GOTOXY:
    stx CH
    sty CV
    jsr VTAB
    rts

EXIT:
    dec $03F4
    jsr  $BF00
    .byte   $65
    .word   PARMTABLE

PARMTABLE:
    .byte   $04
    .byte   $00
    .word   $0000
    .byte   $00
    .word   $0000

MErrEnvM:
    ascz "PROG WON'T RUN"

MErr80Col:
    ascz "PROG REQUIRES 80-COL MODE"

MErrgen:
    ascz "AN ERROR OCCURRED"
    

screenshot*

disk image PROG.po.zip

Thanks!

PS: This error doesn't depend on the "cheap"/unnamed labels, the logic sequence or the compiler.


UPDATE #1:

build.sh

#!/usr/bin/env bash

ca65 --cpu 6502 -t apple2 -l main.lst main.asm -o main.o
ld65 -o PROG -C main.cfg -m main.map main.o

...
exit 0

main.cfg

SYMBOLS {
    __FILETYPE__: type = weak, value = $00FF; # ProDOS file type (SYS)
    __STACKSIZE__: type = weak, value = $0800; # 2k stack
}
MEMORY {
    RAM:    file = %O, define = yes, start = $2000,         size = $BF00 - $2000,         fill=yes;
    BSS:    file = "",               start = __RAM_LAST__,  size = $BF00 - __RAM_LAST__;
}
SEGMENTS {
    CODE:     load = RAM,   type = ro;
    RODATA:   load = RAM,   type = ro;
    BSS:      load = RAM,   type = bss;
}


UPDATE #2:

Disassembled as:

da65 --cpu 6502 --start-addr=$2000 -o PROG.dasm PROG

Output:

; da65 V2.18 - N/A
; Created:    2023-10-22 17:45:36
; Input file: PROG
; Page:       1


        .setcpu "6502"

L0004           := $0004
L203A           := $203A
L2076           := $2076
L207E           := $207E
        cld
        ldx     #$FF
        txs
        lda     #$69
        sta     $03F2
        lda     #$FF
        sta     $03F3
        eor     #$A5
        sta     $03F4
        jsr     LFC58
        jsr     LFE84
        jsr     LFE89
        jsr     LFE93
        lda     LBF98
        and     #$A8
        cmp     #$A8
        bcs     L6130
        clc
        lda     #$02
        bit     LBF98
        beq     L6135
L6130:  lda     #$01
        jmp     L203A

L6135:  lda     #$02
        jmp     L203A

        cmp     #$01
        beq     L6144
        cmp     #$02
        beq     L614E
        bne     L6158
L6144:  lda     #$8E
        sta     $06
        lda     #$20
        sta     $07
        beq     L6160
L614E:  lda     #$9D
        sta     $06
        lda     #$20
        sta     $07
        beq     L6160
L6158:  lda     #$B7
        .byte   $85
L615B:  asl     $A9
        jsr     $0785
L6160:  ldx     #$00
L6162:  ldy     #$17
        jsr     L2076
        ldy     #$00
L6169:  lda     ($06),y
        beq     L6173
        jsr     LFDED
        iny
L6171:  bne     L6169
L6173:  jmp     L207E

        stx     $24
        sty     $25
        jsr     LFC22
        rts

        dec     $03F4
        jsr     LBF00
        adc     $87
        jsr     L0004
        brk
        brk
        brk
        brk
        brk
        bne     L6162
        .byte   $CF
        .byte   $C7
        ldy     #$D7
        .byte   $CF
        dec     LD4A7
        ldy     #$D2
        cmp     $CE,x
        brk
        bne     L6171
        .byte   $CF
        .byte   $C7
        ldy     #$D2
        cmp     $D1
        cmp     $C9,x
        .byte   $D2
        cmp     $D3
        ldy     #$B8
        bcs     L615B
        .byte   $C3
        .byte   $CF
        cpy     LCDA0
        .byte   $CF
        cpy     $C5
        brk
        cmp     ($CE,x)
        ldy     #$C5
        .byte   $D2
        .byte   $D2
        .byte   $CF
        .byte   $D2
        ldy     #$CF
        .byte   $C3
        .byte   $C3
        cmp     $D2,x
        .byte   $D2
        cmp     $C4
        ...
        brk

UPDATE #3:

java -jar acx-1.8.0.jar create -d PROG.po --prodos-order --name=PROG --format=ProDOS_2_4_2.dsk --prodos --size=140kb
java -jar acx-1.8.0.jar import --dos PROG --disk=PROG.po --name=PROG.SYSTEM -t=sys --aux=8192
java -jar acx-1.8.0.jar unlock -d PROG.po BASIC.SYSTEM
java -jar acx-1.8.0.jar del -d PROG.po BASIC.SYSTEM
java -jar acx-1.8.0.jar lock -d PROG.po PROG.SYSTEM

Solution

  • Alright. There are few points to mention, based on this discussion on GitHub.

    1. I managed to learn how to properly create and manage disk images created for Apple II' computers. =)
    2. The current version of AppleCommander (ACX) needs to be upgraded to be able to properly import binary files. Hopefully, in version 1.9 we'll be able to use the full-functional import feature.

    Many thanks to all who helped in finding the answers.