assembly 修改的6502中断返回

vwhgwdsa  于 2022-11-24  发布在  其他
关注(0)|答案(3)|浏览(146)

中断返回时,我正在尝试切换正常程序流:

START
    SEI
    LDX #<IRQ
    LDY #>IRQ
    STX $FFFE
    STY $FFFF
    CLI

LOOP1
    INC $D020
    JMP LOOP1

LOOP2
    INC $D021
    JMP LOOP2

IRQ
    STA SAVEA+1
    STX SAVEX+1
    STY SAVEY+1

    // Some Routines

    LDA #$00
    PHA
    LDA #<LOOP2
    PHA
    LDA #>LOOP2
    PHA

SAVEA   
    LDA #$00
SAVEX   
    LDX #$00
SAVEY   
    LDY #$00
    RTI

我写这段代码是根据源代码:http://6502.org/tutorials/interrupts.html#1.3

但PHA会导致崩溃,如何在中断中将正常流程LOOP1切换到LOOP2?

um6iljoc

um6iljoc1#

最简单的方法可能是有两个堆栈区--每个任务一个。例如,$100-$17f和$180-$1ff。然后,你可以让中断任务切换代码如下:

pha
  txa
  pha
  tya
  pha ;saving task's registers on its stack,
      ;where flags and PC are already saved
      ;by entering the interrupt

  tsx
  stx ... ;save task's stack position

  ... ;select new task to run/etc.

  ldx ...
  txs ;load other task's stack position

  pla
  tay
  pla
  tax
  pla ;restore other task's registers

  rti ;and finally continue other task
fafcakar

fafcakar2#

简单的办法就是:

TSX
LDA #$00
STA $0101,X   // Processor Status
LDA #<LOOP2
STA $0102,X   // Task Low Address
LDA #>LOOP2
STA $0103,X   // Task High Address

但是对于更复杂的任务管理,我们必须为每个任务保存A、X、Y寄存器:

START
    SEI
    LDX #<IRQ
    LDY #>IRQ
    STX $FFFE
    STY $FFFF
    CLI

LOOP1
    INC $D020
    JMP LOOP1

LOOP2
    INC $D021
    JMP LOOP2

IRQ
    STA $FF
    STX $FE
    STY $FD
    LDX TASK+1
    CPX TASK
    BEQ CONT
    LDY TASKI,X
    TSX
    LDA $0101,X
    STA TASKS+0,Y
    LDA $0102,X
    STA TASKS+1,Y
    LDA $0103,X
    STA TASKS+2,Y
    LDA $FF
    STA TASKS+3,Y
    LDA $FE
    STA TASKS+4,Y
    LDA $FD
    STA TASKS+5,Y
    LDA TASK
    STA TASK+1
CONT

    // Change Task
    LDA TASK
    CLC
    ADC #$01
    AND #$01
    STA TASK

    LDX TASK
    CPX TASK+1
    BEQ CONT2
    STX TASK+1
    LDY TASKI,X
    TSX
    LDA TASKS+0,Y
    STA $0101,X
    LDA TASKS+1,Y
    STA $0102,X
    LDA TASKS+2,Y
    STA $0103,X
    LDA TASKS+3,Y
    STA $FF
    LDA TASKS+4,Y
    STA $FE
    LDA TASKS+5,Y
    STA $FD
CONT2
    LDA $FF
    LDX $FE
    LDY $FD
    RTI

TASK
    .BYTE 0,0
TASKI
    .BYTE 0,6,12,18,24,30,36
TASKS
    .BYTE 0,<LOOP1,>LOOP1,0,0,0
    .BYTE 0,<LOOP2,>LOOP2,0,0,0
q9yhzks0

q9yhzks03#

我不确定您要做什么,但在我看来,您好像要快速连续地更改Commodore 64的背景颜色。如果您要更改正在执行的操作,实际上有一个更简单的方法:

START
    SEI
    LDX #<IRQ
    LDY #>IRQ
    STX $FFFE
    STY $FFFF
    CLI

LOOP1
    INC $D020   ;the interrupt will switch this to $D021 and back every time it happens.
    JMP LOOP1

IRQ
    PHA
       LDA #$01
       EOR LOOP1+1  ;the value at this address is the "20" in "INC $D020"
       STA LOOP1+1  ;toggle between "INC $D020" and "INC $D021" each IRQ
    PLA
    RTI

这比设置一个标志并根据该标志进行分支要少得多。假设您的目标是尽快更新边框颜色/背景颜色,这将大大减少检查条件所花费的时间。

相关问题