Search code examples
assembly6502c64

Modified 6502 Interrupt Returns


I am trying to switch normal program flow while an interrupt 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 #$00
    PHA
    LDA #<LOOP2
    PHA
    LDA #>LOOP2
    PHA

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

I wrote this code accourding to that source: http://6502.org/tutorials/interrupts.html#1.3

enter image description here

But PHA's cause crash, how to switch normal flow LOOP1 to LOOP2 in an interrupt?


Solution

  • Simple way is:

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

    But for more complex task management, we have to save A,X,Y registers for each task:

    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