User Tools

Site Tools


base:the_double_irq_method

Differences

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

Link to this comparison view

Next revision
Previous revision
base:the_double_irq_method [2015-04-17 04:34] – external edit 127.0.0.1base:the_double_irq_method [2016-11-05 21:12] (current) – [Theory] monte_carlos
Line 14: Line 14:
 It's quite easy, let's configure a raster IRQ at raster line X to pull the CPU out of the main-code. This IRQ will jitter with 7 cycles at most since the main code can be anything. Now, immediatly let's configure the VIC to trigger another raster IRQ at line X+1. We're almost at X+1 but quite not there yet so let's just fill up with NOPs. This would ensure that when the second IRQ occurs we know 100% that the CPU will be executing NOPs and thus give us a jitter of only 1 cycle at line X+1. It's quite easy, let's configure a raster IRQ at raster line X to pull the CPU out of the main-code. This IRQ will jitter with 7 cycles at most since the main code can be anything. Now, immediatly let's configure the VIC to trigger another raster IRQ at line X+1. We're almost at X+1 but quite not there yet so let's just fill up with NOPs. This would ensure that when the second IRQ occurs we know 100% that the CPU will be executing NOPs and thus give us a jitter of only 1 cycle at line X+1.
  
-(will continue soon... ;D )+Remember that the C64 has two irq pointer locations? One at $fffe in the ROM memory which is due to hardware design and one at $0314 in RAM which is just a memory location the kernal uses to indirect call a user irq handlerWe can use both pointer to accomplish the task of irq jitter correctionThe first irq, which contains the "nop" list, is called by the $0314 pointer with a cpu port value of $37 or $36The second irq which just has a jitter of 1 cycle is called by the rom pointer at $fffe with a cpu port value of $35. 
 +The trick is to set up these pointers beforehand and within the irq code just toggle the cpu port value to toggle the irq targets. The number of nops can be determined by just removing one after each other until the part crashes. Then add again one nop. 
 +This is how it is done in the following code example where $0314 points to "irq0" and $fffe points to "irq"
 +The three pla just removes the pc and status from the stack which were pushed at the moment the second irq was triggered. However after the second irq ends we want to jumpback to the main program and not somewhere in the middle of the nop list. 
 +The inc $d012 in the first irq must come early so we  sntill in the rasterline previous to the rastene in which the secondn irq should be triggered. The same applies for the dec $d012 in the second irq for similar reasons. 
 +After the three pla some timing opcodes follow. These assure that we are at the end of a rasterline when the lda $d012 is beeing performed. The compare tests, if the load occured in rasterline N or N+1 and wastes a cycle in the first case. As an effect the lines after the branch are executes always at the same rasterbeam position. The irq is stable, now. 
 + 
 + 
 +<code> 
 + 
 +.PROC irq0 
 + inc $d012 
 + lsr $d019 
 + dec $01 
 + cli 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 + nop 
 +.ENDPROC 
 + 
 +.PROC irq 
 + dec $d012 
 + 
 + pla 
 + pla 
 + pla 
 + 
 + lda (0,x) 
 + lda (0,x) 
 + lda (0,x) 
 + lda (0,x) 
 + nop 
 + bit 2 
 + bit 2 
 + lda $d012 
 + cmp #$39 
 + beq fixcycle 
 +fixcycle bit $d020 
 +... 
 + 
 +</code> 
 + 
 +The corresponding irq init looks like this: 
 + 
 +<code> 
 +.PROC irqInit 
 + lda #$7f 
 + sta $dc0d 
 + bit $dc0d 
 + lda #$81 
 + sta $d01a 
 + lda #<irq0 
 + sta $0314 
 + lda #>irq0 
 + sta $0315 
 + lda #<irq 
 + sta $fffe 
 + lda #>irq 
 + sta $ffff 
 + lda #$38 
 + sta $d012 
 + lda #$36 
 + sta $01 
 + lsr $d019 
 + rts 
 +.ENDPROC 
 + 
 +The lsr $d019 at the end of the init is performed to clear the irq request if for some reason a rasterirq request is rised during init. 
 + 
 +</code>
base/the_double_irq_method.txt · Last modified: 2016-11-05 21:12 by monte_carlos