6502 RTS 实用程序所需的堆栈上的 JSR 更改作为“函数调用”

问题描述 投票:0回答:1

处女邮局 6502 JSR 调用将 2 个字节压入堆栈,这些字节必须位于 RTS 堆栈的“顶部”。 使用 JSR 将 6502 代码组织成函数来解决以下困境是否有一个好的实践: 假设以下1:“函数调用”和2:“函数”

ldx #$00
ldy #$01
lda cursor_x
pha
lda cursor_y
jsr set_sprite_x_y_sa

set_sprite_x_y_sa: 
;u have to use stack..
;or ram/rom
;ldx #$00
;ldy #$01
;lda cursor_x ;(!)
;pha          ;(!)
;lda cursor_y ;(!)

; y position
sta oam, X
inx
; tile
tya ; transfer val y to a
sta oam, X
inx
; attributes
lda #%00000000 ; no flip
sta oam, X
inx
; x position
pla
sta oam, X
rts

除非用(!)标记的行没有被注释掉,否则程序将无法运行,因为pla从堆栈返回部分返回地址。 堆栈可以弹出并存储两次以从堆栈中获取预期值, 然后推回两次以取悦 rts,但没有足够的寄存器来做到这一点(必须使用 X)。 那么剩下的唯一选择是仅将堆栈与累加器结合使用,并使 x 和 y 寄存器闲置存储必须在 rts 之前推回的 16 位吗? 或者是否有一些聪明而快速的方法来使用 SP 操作堆栈。 盖尔盖利

这里没有太多要补充的

6502
1个回答
0
投票

我有一个控制代码字节表(CONCODEC),我扫描该表以查找匹配的代码,从而为我提供所需跳转地址的索引。

该值被加载到 .Y 中,该 .Y 索引到子例程地址高/低字节表中 (CONCODEL/CONCODEH)。

这些高/低字节被推入堆栈,然后进行 RTS(本质上是 BASIC 术语中的 ON...GOSUB 开关)。这些子例程 RTS 首先回到所谓的跳转逻辑。

您必须确保地址高字节减去 1,因为 RTS 会自动将其加回来。

    CONCODEC:
    .pc = * "CONCODEC"      // Control character code data
    .byte vic20.screencodes.WHITE,vic20.screencodes.CBMOFF, ... etc

    CONCODEL:
    .pc = * "CONCODEL"      // Control character handler lo-bytes
    .byte <controlcode_handler.set_colour_byte-1,<controlcode_handler.shift_cbm-1, ... etc

    CONCODEH:
    .pc = * "CONCODEH"      // Control character handler hi-bytes
    .byte >controlcode_handler.set_colour_byte-1,>controlcode_handler.shift_cbm-1, ... etc


    // Switch to subroutine with CONCODEC in .Y
    lda CONCODEH,y          // [4]  get control code handler address hi-byte
    pha                     // [3]  push to Stack
    lda CONCODEL,y          // [4]  get control code handler address lo-byte
    pha                     // [3]  push to Stack
    rts                     // [6]  return via control code handler
© www.soinside.com 2019 - 2024. All rights reserved.