1

I was following this tutorial on Commodore 64 timer interrupts and tried to replicate it (except all I was planning on doing was changing the border color.) I noticed that my interrupt only occurs once, and never triggers again. I don't understand why. (Just as an aside, when I first tested this, I also had a scanline IRQ set up and it worked fine, except it also halted the main program and only interrupts could run!)

Here's a minimal reproducible example. The border color changes from light blue to light gray and never again (only one inc $D020 gets executed.) I tried changing the timer values a bit but it doesn't make a difference, the IRQ only happens once. What did I miss?

    org $0801       

    ;INIT CODE
    db $0E,$08,$0A,$00,$9E,$20,$28,$32,$30,$36,$34,$29,$00,$00,$00  
    
    sei
    
    lda #%01010010
    STA $DC0F
    ;TIMER B COUNTS TIMER A UNDERFLOW
    ;LOAD START VALUE INTO TIMER,
    ;INDICATE TIMER UNDERFLOW ON PORT B BIT 7
    

    LDA #$FF
    STA $DC04
    
    LDA #$00    
    STA $DC05       ;LOAD TIMER 1 WITH VALUE $00FF
    
    LDX #$01
    
    STX $DC06
    DEX
    STX $DC07       ;LOAD TIMER 2 WITH VALUE $0001
    
    
    LDA #<IRQ
    STA $0314
    LDA #>IRQ
    STA $0315       ;LOAD IRQ VECTOR WITH IRQ ROUTINE ADDR.
    
    LDA #%00010001
    STA $DC0E       ;TURN ON TIMER 1 AND LOAD THE START VALUE
    

    CLI
    
    
forever:
    jmp forever
    
    
IRQ:
    LDA #%01111111
    STA $DC0D   
    LDA $DC0D   ;IRQ ACK
    
    INC $D020   ;UPTICK THE BORDER COLOR
    
    
    pla
    tay
    pla
    tax
    pla
    rti
5
  • Without going deep, I can't see any setting for timer A control, like having it reload every time used. Similar no check if it's really a timer interrupt - after all, IRQ is as well hit once per frame for the jiffy clock - which as well doesn't get served from your routine. Last, but for sure not least, what are the values you're using? It seems the effective interrupt rate is every 255 cycles. Quite short. That's close to 4000 times per second. With the right harmonic this may quite well look like no change at all.
    – Raffzahn
    Jan 1 at 3:09
  • Originally I had Timer A at $03FC and Timer B at $FFFF and it made no difference. Also, if it's the only IRQ enabled doesn't that mean by default it has to be from the timer? I tried reloading the timer in the IRQ handler body but no luck there either Jan 1 at 4:07
  • Did you miss to push the register values at the start of the interrupt handler? Jan 3 at 20:10
  • @MartinRosenau The KERNAL does that for you. Jan 3 at 20:37
  • I'm a VIC-20 coder (3.5K RAM should be enough for anybody) so I don't know if the C64 CIAs work similarly to the VIAs I'm familiar with, but on the VIC you have to acknowledge the current IRQ from VIA #2 before the next will hit the CPU. This is done by reading the VIA #2 timer #1 countdown lo-byte latch (e.g. BIT $9124). Jan 6 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.