User Tools

Site Tools


base:variable_speedcode_runlength

Differences

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

Link to this comparison view

Next revision
Previous revision
base:variable_speedcode_runlength [2016-04-16 11:42] – created bitbreakerbase:variable_speedcode_runlength [2022-01-14 12:45] (current) bitbreaker
Line 1: Line 1:
 +====== Variable speedcode runlength ======
  
 After you entered a segment of speed code at a certain spot by making use of some method discussed in the Article "[[Dispatch on a byte]]" we now want to exit that code at a certain spot. After you entered a segment of speed code at a certain spot by making use of some method discussed in the Article "[[Dispatch on a byte]]" we now want to exit that code at a certain spot.
Line 6: Line 6:
  
 <code> <code>
 +                        ;<- enter here
         sta $0400         sta $0400
         sta $0401         sta $0401
Line 15: Line 16:
         sta $0407         sta $0407
         sta $0408         sta $0408
 +                        ;<- leave here
         sta $0409         sta $0409
         sta $040a         sta $040a
Line 24: Line 26:
 </code> </code>
  
-So given the above example, we might want to enter at sta $0400 and leave after sta $0408, to do so we can modify the code and transform the upcoming sta to an rts command. After exiting the speedcode we then modify the rts back to a sta. Pretty nuch overhead and we would even need to call our speedcode as a subroutine. +So given the above example, we might want to enter at sta $0400 and leave after sta $0408, to do so we can modify the code and transform the upcoming sta to an rts command. After exiting the speedcode we then modify the rts back to a sta. Pretty much overhead and we would even need to call our speedcode as a subroutine. We can also leave the speedcode by a timed NMI, but that will also mean overhead in setting up and it will cost extra cycles for the IRQ and RTI
-If we speedocde with predictable runlengths (so no random penalty cycles apply) we could set up a timer irq that will trigger just at the right moment. Thusno more code modification is needed and the setup is pretty simple.+ 
 +We need speedcode with predictable runlengths (so no random penalty cycles apply) to do soThe setup is quite simple and no code has to be restored
  
 All you need is setting up a IRQ/NMI handler once beforehand as the exit point of your routine, setup the timer with 2 writes to e.g. $dd04/$dd05 and start a single shot timer run by setting $dd0e to $09. All you need is setting up a IRQ/NMI handler once beforehand as the exit point of your routine, setup the timer with 2 writes to e.g. $dd04/$dd05 and start a single shot timer run by setting $dd0e to $09.
Line 36: Line 39:
           lda #$08           lda #$08
           sta $dd0e           sta $dd0e
 +          lda #$00
 +          sta $dd04
 +          sta $dd05
           lda $dd0d           lda $dd0d
           lda #$81           lda #$81
Line 49: Line 55:
           sta $dd04           sta $dd04
           ;this can even be ommitted if we do not run more than 255 cycles           ;this can even be ommitted if we do not run more than 255 cycles
-          lda runlength_hi,+          ;lda runlength_hi,
-          sta $dd05+          ;sta $dd05 
 + 
 +          tsx
                      
           lda #$09           lda #$09
Line 80: Line 88:
           !byte $00,$00,$00,$00,$00 ...           !byte $00,$00,$00,$00,$00 ...
 exit exit
-          tsx 
-          txa 
-          sbx #$03 
           txs           txs
           cli           cli
Line 90: Line 95:
  
 Regarding the cli instruction: This is important, as else normal irqs might be blocked until we restore the I-flag on the terminating rti, so find out for yourself if it is needed in your case. If so, you can just pull the original PC and flags from stack via pla/plp, instead of manipulating the stack pointer, or simply forgo on the cli if no further irq needs to happen. Regarding the cli instruction: This is important, as else normal irqs might be blocked until we restore the I-flag on the terminating rti, so find out for yourself if it is needed in your case. If so, you can just pull the original PC and flags from stack via pla/plp, instead of manipulating the stack pointer, or simply forgo on the cli if no further irq needs to happen.
- 
base/variable_speedcode_runlength.1460799745.txt.gz · Last modified: 2016-04-16 11:42 by bitbreaker