User Tools

Site Tools


base:stable_raster_routine

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

base:stable_raster_routine [2015-04-17 04:34] (current)
Line 1: Line 1:
 +======= STABLE RASTER ROUTINE =======
  
 +A Raster Stabbing routine using the double IRQ principle. Insert this code after you have pushed your registers onto the stack inside your IRQ code. The routine doesen'​t care what the actual $d012 value is so it is flexible.
 +
 +Other Interrupts, $d012 = #$ff, Sprites, Badline and Badline-1 = fuckup.
 +
 +If you have the KERNAL banked in, you need to modify the IRQ-Vectors.
 +
 +
 +Kickassembler format
 +
 +<​code>​
 +//​«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»
 +// Raster Stabilizing Code
 +//​«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»
 +    // A Raster Compare IRQ is triggered on cycle 0 on the current $d012 line
 +    // The MPU needs to finish it's current OP code before starting the Interrupt Handler,
 +    // meaning a 0 -> 7 cycles delay depending on OP code.
 +    // Then a 7 cycle delay is spendt invoking the Interrupt Handler (Push SR/PC to stack++)
 +    // Then 13 cycles for storing registers (pha, txa, pha, tya, pha)
 +
 +    // CYCLECOUNT: [20 -> 27] cycles after Raster IRQ occurred.
 +
 +    // Set up Wedge IRQ vector
 +    lda #<​WedgeIRQ
 +    sta $fffe
 +    lda #>​WedgeIRQ
 +    sta $ffff
 +
 +    // Set the Raster IRQ to trigger on the next Raster line
 +    inc $d012
 +
 +    // Acknowlege current Raster IRQ
 +    lda #$01
 +    sta $d019
 +
 +    // Store current Stack Pointer (will be messed up when the next IRQ occurs)
 +    tsx
 +
 +    // Allow IRQ to happen (Remeber the Interupt flag is set by the Interrupt Handler).
 +    cli
 +
 +    // Execute NOPs untill the raster line changes and the Raster IRQ triggers
 +    NOP
 +    NOP
 +    NOP
 +    NOP
 +    NOP
 +    NOP
 +    NOP
 +    NOP
 +    // Add one extra nop for 65 cycle NTSC machines
 +
 +    // CYCLECOUNT: [64 -> 71]
 +
 +WedgeIRQ:
 +    // At this point the next Raster Compare IRQ has triggered and the jitter is max 1 cycle.
 +    // CYCLECOUNT: [7 -> 8] (7 cycles for the interrupt handler + [0 -> 1] cycle Jitter for the NOP)
 +
 +    // Restore previous Stack Pointer (ignore the last Stack Manipulation by the IRQ)
 +    txs
 +
 +    // PAL-63 ​ // NTSC-64 ​   // NTSC-65
 +    //​---------//​------------//​-----------
 +    ldx #$08   // ldx #$08   // ldx #$09
 +    dex        // dex        // dex
 +    bne *-1    // bne *-1    // bne *-1
 +    bit $00    // nop
 +               // nop
 +
 +    // Check if $d012 is incremented and rectify with an aditional cycle if neccessary
 +    lda $d012
 +    cmp $d012  // <- critical instruction (ZERO-Flag will indicate if Jitter = 0 or 1)
 +
 +    // CYCLECOUNT: [61 -> 62] <- Will not work if this timing is wrong
 +
 +    // cmp $d012 is originally a 5 cycle instruction but due to piplining tech. the
 +    // 5th cycle responsible for calculating the result is executed simultaniously
 +    // with the next OP fetch cycle (first cycle of beq *+2).
 +
 +    // Add one cycle if $d012 wasn't incremented (Jitter / ZERO-Flag = 0)
 +    beq *+2
 +
 +    // Stable code    ​
 +    ​
 +</​code>​
 +
 +Don't forget to set up the next IRQ-Vector before exiting the IRQ.
 +
 +If you want to make it more simple, you could store this as a pseudo or macro (STABILIZE) and just:
 +
 +<​code>​
 +IRQ_Begin:
 +    pha
 +    txa
 +    pha
 +    tya
 +    pha
 +    :STABILIZE
 +    ​
 +    //​..xxXX[Stable Code]XXxx..
 +    ​
 +    lda #<​Next_IRQ
 +    sta $fffe
 +    lda #>​Next_IRQ
 +    sta $ffff
 +    lda #$01
 +    sta $d019
 +    pla
 +    tay
 +    pla
 +    tax
 +    pla
 +    rti
 +
 +</​code>​
 +
 +TWW/​Creators
base/stable_raster_routine.txt · Last modified: 2015-04-17 04:34 (external edit)