修改 6502 中断 Returns

Modified 6502 Interrupt Returns

我正在尝试在中断时切换正常程序流程 returns:

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 #[=11=]
    PHA
    LDA #<LOOP2
    PHA
    LDA #>LOOP2
    PHA

SAVEA   
    LDA #[=11=]
SAVEX   
    LDX #[=11=]
SAVEY   
    LDY #[=11=]
    RTI

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

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

最简单的事情可能是有两个堆栈区域 -- 每个任务一个。例如,$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 

简单的方法是:

TSX
LDA #[=10=]
STA 01,X   // Processor Status
LDA #<LOOP2
STA 02,X   // Task Low Address
LDA #>LOOP2
STA 03,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 01,X
    STA TASKS+0,Y
    LDA 02,X
    STA TASKS+1,Y
    LDA 03,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 #
    AND #
    STA TASK


    LDX TASK
    CPX TASK+1
    BEQ CONT2
    STX TASK+1
    LDY TASKI,X
    TSX
    LDA TASKS+0,Y
    STA 01,X
    LDA TASKS+1,Y
    STA 02,X
    LDA TASKS+2,Y
    STA 03,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