Tezz Posted November 14, 2007 Share Posted November 14, 2007 (edited) I've been continuing on with coding today and planning some routines.. I'm still thinking about the best way to implement this one though... I need to rotate 6 colour values around 6 colour registers within a VBI routine with a delay included to control the speed. with the delay I was thinking about incrementing a counter so on each pass through the vbi routine when the counter reaches number X the colour values then rotate to the next value. So, for example: I have the colour values 02,04,06,08,0A,0C, I want to apply these values to colour registers: COLPM0, COLPM1, COLPM2, COLPM3, COLPF0, COLPF1 and rotate the values round the registers in an endless loop with the delay timer. That's pretty straight forward I hear you shout.. well yes, but as it's critical to execute routines optimally during the vbi I wondered if there are any examples of such a routine out there? Thanks, Tezz Edited November 14, 2007 by Tezz Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted November 14, 2007 Share Posted November 14, 2007 a quick "out of brain" code without testing... dec delay lda delay bmi cycle ... cycle: lda #value sta delay ;now rotate from right to left ldx colortab lda colortab+1 sta colortab lda colortab+2 sta colortab+1 lda colortab+3 sta colortab+2 lda colortab+4 sta colortab+3 lda colortab+5 sta colortab+4 stx colortab+5 ... ldx #5 loop: lda colortab,x sta colpm0,x dex bpl loop ... colortab: dta 2,4,6,8,10,12 does this make sense? Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted November 14, 2007 Share Posted November 14, 2007 a quick "out of brain" code without testing...ditto here... Sometimes I find that wasting a few more 'data' areas can save you some of code space (and hence a few cycles too), note the extra zero used on the end of the colour table. e.g. ... ldx ct_offset ldy #0 loop: lda colortab,x sta colpm0,y inx iny cpy #6 bne loop lda colortab,x bne no_reset sta ct_offset no_reset: ... colortab: .byte 2,4,6,8,10,12 .byte 2,4,6,8,10,0 Regards, Mark Quote Link to comment Share on other sites More sharing options...
Tezz Posted November 15, 2007 Author Share Posted November 15, 2007 Brilliant! That's a great help. It all makes sense! @ Wrathchild, @ Heaven/TQA.. Thanks once again guys Quote Link to comment Share on other sites More sharing options...
Tezz Posted November 27, 2007 Author Share Posted November 27, 2007 (edited) @ Heaven Thanks for the code example earlier, I got around to running some test Vblank programs yesterday, the first to move all the P/Ms around from a table which worked fine but for some reason the other test for the colour cycling which I based from your example crashes the emulated Atari? I'm missing an obvious mistake I must have made here somewhere? I can see the routine change the registers briefly before it crashes Any ideas? Edited November 28, 2007 by Tezz Quote Link to comment Share on other sites More sharing options...
Rybags Posted November 27, 2007 Share Posted November 27, 2007 bpl loop ctab: .byte $2 An opcode ending in $02 is guaranteed to lockup a machine. You need JMP $E45F after the BPL LOOP (or $E462 if it's a deferred VB). Quote Link to comment Share on other sites More sharing options...
Tezz Posted November 28, 2007 Author Share Posted November 28, 2007 (edited) bpl loop ctab: .byte $2 An opcode ending in $02 is guaranteed to lockup a machine. You need JMP $E45F after the BPL LOOP (or $E462 if it's a deferred VB). Thanks! Gees that's the second time in the past few days I've made a simple and obvious mistake and not noticed it! I can't believe I forgot to JMP XITVBV .. Doh! It works fine now.. Thanks again. Edited November 28, 2007 by Tezz Quote Link to comment Share on other sites More sharing options...
Tezz Posted December 1, 2007 Author Share Posted December 1, 2007 (edited) Hi All, I'm stuck on the delay and wondered if anyone can help.. I've been using the internal realtime clock as a timer to make a delay in my vbi, I created a quick test vbi program to move a player from left to right using the timer like this below... TIMER equ $14 ; internal realtime clock LDA #0 STA OFFSET STA SIZEP0 LDA TIMER AND #1 ; delay BNE EXIT INC POSITION LDA POSITION STA HPOSP0 EXIT: JMP XITVBV so, that works out fine, the value #1 can be increased to delay the move more and more So, now with that test out of the way and back to my actual vbi routine I have the colours rotating from the values in a table however I need to now add in the delay before the new values store as it is too fast. This is where I'm stuck, I was using bpl to branch if positive in the colour storing loop but of course I cannot use LDA TIMER AND#1 before the bpl as that will prevent the bpl from doing it's job in the loop so this code below screws up the vbi. ldx #5 loop: lda ctab,x sta colpm0,x dex LDA TIMER AND #1 bpl loop jmp XITVBV So, knowing that that wasn't going to work I tried instead to use cpx and bne to compare when X has reached 0 so I wrote the code like this... ldx #5 loop: lda ctab,x sta colpm0,x dex LDA TIMER AND #1 cpx #0 bne loop jmp XITVBV This only stopped colpm3 from being updated in the loop rather than what i need to do in delaying the storing of the values to make the rotation slower. I then tried dropping the timer idea and making a loop instead like this code below but it had the same effect only stopping colpm3 from being updated in the loop.. ldx #5 loop: lda ctab,x sta colpm0,x jsr count dex cpx #0 bne loop jmp XITVBV ctab: .byte $2,$4,$6,$8,$A,$C delay .byte $32 count: dec delay lda delay bmi cycle cycle: lda #32 sta delay rts So i'm stuck there with it, I can't seem to get the delay before storing to work?? Edited December 1, 2007 by Tezz Quote Link to comment Share on other sites More sharing options...
kenfused Posted December 2, 2007 Share Posted December 2, 2007 (edited) I am not sure exactly what you are trying to do here and what you mean by too fast? where does ctab get filled in? edit: ah I read back a little farther in the thread. I think you want to be doing the loop to copy ctab to the color everytime. It is the part where you are actually rotating the colors in ctab that you want to skip based on the timer. Edited December 2, 2007 by kenfused Quote Link to comment Share on other sites More sharing options...
Tezz Posted December 2, 2007 Author Share Posted December 2, 2007 (edited) I am not sure exactly what you are trying to do here and what you mean by too fast? where does ctab get filled in? edit: ah I read back a little farther in the thread. I think you want to be doing the loop to copy ctab to the color everytime. It is the part where you are actually rotating the colors in ctab that you want to skip based on the timer. Hi Ken, thanks for the reply. in my vbi, the part of the code for the actual loop to rotate through the 6 values in the table (without the delay yet) is like this below.. ldx #5 loop: lda ctab,x sta colpm0,x dex bpl loop jmp XITVBV I assumed that the delay must now come before it stores the values to the colour registers, EDIT ** I mean before the next time around in the loop so I added the timer like this ldx #5 loop: lda ctab,x sta colpm0,x dex LDA TIMER AND #1 bpl loop jmp XITVBV but that just crashes the Atari, i think this is because the loop is waiting for a branch when positive checking the status so adding lda timer and #1 messes that up. I tried instead to do it in a few different ways like in the above post but all my attempts didn't work, they either crashed the Atari or didn't add the speed delay? the only code before that loop is Heavens example at the start of this thread to rotate the values in the table once on each pass through which works fine, i just need to delay the speed that the actual colours store and hence slow the speed that the colours rotate around. Thanks, Tezz EDIT ** I just tried this below, it didn't crash the atari but it also had no effect on the speed at all ldx #5 loop: LDA TIMER AND #1 lda ctab,x sta colpm0,x dex bpl loop jmp XITVBV Edited December 2, 2007 by Tezz Quote Link to comment Share on other sites More sharing options...
simonl Posted December 2, 2007 Share Posted December 2, 2007 Is what you're trying to do make it so that the colour change doesn't happen every frame e.g. only happens once every couple of seconds? If so, I would reckon the best way of doing it is to count frames rather than trying to introduce a delay inside your VBI routine (any sort of delay in a time critical thing like an interrupt routine is generally a bad idea as you can crash the machine). Something like this might do the trick: FCOUNT .BYTE $31 ; Every 50 frames ; VBLRTN PHA TXA PHA LDX FCOUNT DEX ; Have we waited the desired number of frames CPX #$00 BNE DONE ; If so, do whatever it is you're doing e.g. LDA BAK ADC $0F STA BAK ; Reset the frame counter LDX #$31 ; Store new frame counter value DONE STX FCOUNT PLA TAX PLA JMP XITVBV Quote Link to comment Share on other sites More sharing options...
Tezz Posted December 2, 2007 Author Share Posted December 2, 2007 Is what you're trying to do make it so that the colour change doesn't happen every frame e.g. only happens once every couple of seconds? If so, I would reckon the best way of doing it is to count frames rather than trying to introduce a delay inside your VBI routine (any sort of delay in a time critical thing like an interrupt routine is generally a bad idea as you can crash the machine). Something like this might do the trick: FCOUNT .BYTE $31 ; Every 50 frames ; VBLRTN PHA TXA PHA LDX FCOUNT DEX ; Have we waited the desired number of frames CPX #$00 BNE DONE ; If so, do whatever it is you're doing e.g. LDA BAK ADC $0F STA BAK ; Reset the frame counter LDX #$31 ; Store new frame counter value DONE STX FCOUNT PLA TAX PLA JMP XITVBV Hi, thanks that method sounds like a better idea. Everything I have tried so far crashes. You are right by the way, I'm trying to update the colours from the rotating table roughly every 1/2 second so I think counting the frames is prob a good idea rather than having a delay in the vbi. I was having a rethink before I read your reply and I tried this code below a few minutes ago.. ldx #5 TIMING: INC COUNT ;TIMING LOOP LDA COUNT CMP LIMIT BNE loop loop: LDA #0 STA COUNT ; reset counter lda ctab,x sta colpm0,x dex CPX #0 BNE TIMING bpl LOOP jmp XITVBV ctab: .BYTE $2,$4,$6,$8,$A,$C COUNT: .BYTE $00 ;HOW MANY DELAYS SO FAR LIMIT: .BYTE $08 ;THIS CONTROLS TIME DELAY yet again this just crashes! I'll start working now on implementing your frame count idea! Thanks for your help Quote Link to comment Share on other sites More sharing options...
MaPa Posted December 2, 2007 Share Posted December 2, 2007 (edited) Try to modify it like this, it should make colour change every 8 frames (8/50 seconds, as you had 8 in limit). ldx #5 TIMING: INC COUNT;TIMING LOOP LDA COUNT CMP LIMIT BEQ loop jmp XITVBV loop: LDA #0 STA COUNT; reset counter lda ctab,x sta colpm0,x dex bpl LOOP jmp XITVBV ctab: .BYTE $2,$4,$6,$8,$A,$C COUNT: .BYTE $00;HOW MANY DELAYS SO FAR LIMIT: .BYTE $08;THIS CONTROLS TIME DELAY Edited December 2, 2007 by MaPa Quote Link to comment Share on other sites More sharing options...
Tezz Posted December 3, 2007 Author Share Posted December 3, 2007 (edited) Try to modify it like this, it should make colour change every 8 frames (8/50 seconds, as you had 8 in limit). ldx #5 TIMING: INC COUNT;TIMING LOOP LDA COUNT CMP LIMIT BEQ loop jmp XITVBV loop: LDA #0 STA COUNT; reset counter lda ctab,x sta colpm0,x dex bpl LOOP jmp XITVBV ctab: .BYTE $2,$4,$6,$8,$A,$C COUNT: .BYTE $00;HOW MANY DELAYS SO FAR LIMIT: .BYTE $08;THIS CONTROLS TIME DELAY Thanks, that was a big help! It's nearly there now, the delay is working and is not crashing any more but what the routine is doing now is executing the wait and then it updates all of the values together at once so instead of a slow rotation, it blinks through all the changes every 8 frames. That's my fault in the way I tried to implement the delay at the wrong point, I think it will need to have the timing loop inside the main colour rotate loop before it stores the new colour value Looking at my full vbi code now below, i think it should include the rotating of the values within the table in the loop also.. SETVBV equ $E45C XITVBV equ $E462 colpm0 equ $D012 org $0600 START: PLA LDA #7 LDY #VBROUT&255 LDX #VBROUT/256 JSR SETVBV RTS VBROUT: ldx ctab ; now rotate from right to left lda ctab+1 sta ctab lda ctab+2 sta ctab+1 lda ctab+3 sta ctab+2 lda ctab+4 sta ctab+3 lda ctab+5 sta ctab+4 stx ctab+5 ldx #5 TIMING: INC COUNT ;TIMING LOOP LDA COUNT CMP LIMIT BEQ loop jmp XITVBV loop: LDA #0 STA COUNT ; reset counter lda ctab,x sta colpm0,x dex bpl LOOP jmp XITVBV ctab: .BYTE $2,$4,$6,$8,$A,$C COUNT: .BYTE $00 ;HOW MANY DELAYS SO FAR LIMIT: .BYTE $08 ;THIS CONTROLS TIME DELAY ================================================================================ After thinking about it some more I wrote this below... SETVBV equ $E45C XITVBV equ $E462 colpm0 equ $D012 org $0600 START: PLA LDA #7 LDY #VBROUT&255 LDX #VBROUT/256 JSR SETVBV RTS VBROUT: INC COUNT ;TIMING LOOP LDA COUNT CMP LIMIT BEQ MAIN ;jmp XITVBV MAIN: ldx ctab ; now rotate from right to left lda ctab+1 sta ctab lda ctab+2 sta ctab+1 lda ctab+3 sta ctab+2 lda ctab+4 sta ctab+3 lda ctab+5 sta ctab+4 stx ctab+5 ldx #5 loop: LDA #0 STA COUNT ; reset counter lda ctab,x sta colpm0,x dex bpl VBROUT jmp XITVBV ctab: .BYTE $2,$4,$6,$8,$A,$C COUNT: .BYTE $00 ;HOW MANY DELAYS SO FAR LIMIT: .BYTE $08 ;THIS CONTROLS TIME DELAY This routine is totally wrong this way too! It is only updating one of the colour registers with the 6 values creating a rotating raster bar on each scanline ? I thought this was going to be quite straight forward to do! Any help appreciated! Here's the code structure i am trying to do: START* read the current value from table store the value in colour register (storing to COLPM0 - COLPF1) decrease x to read next value from table (reading right to left) loop this until the final 6th value has been read from the table and stored in the 6th colour register wait 8 frames now rotate the values in the table 1 byte from right to left repeat START until the table has rotated back 6 times to the beginning and then loop Thanks, Tezz Edited December 3, 2007 by Tezz Quote Link to comment Share on other sites More sharing options...
Shawn Jefferson Posted December 4, 2007 Share Posted December 4, 2007 (edited) Try something like this: vbi: inc count lda count cmp limit bne store rotate: lda #0 sta count ldx ctab lda ctab+1 sta ctab lda ctab+2 sta ctab+1 lda ctab+3 sta ctab+2 lda ctab+4 sta ctab+3 lda ctab+5 sta ctab+4 stx ctab+5 store: ldx #5 loop: lda ctab,x sta COLPM0,x dex bne loop jmp XITVBV .zeropage count: .byte 0 .rodata ctab: .byte $02,$04,$06,$08,$0A,$0C limit: .byte $08 The code is doing this: 1. Check if we have counted enough VBIs. If not, jump to store (#3). 2. Clear the count. Rotate the color table (this is your code to rotate the table.) 3. Store the color table values to the color registers. This has to be done every VBI, since the OS will reset them from the shadow registers. Oh, I used cc65 to code this up, so the syntax may look a little wierd to you. testvbi.zip Edited December 4, 2007 by Shawn Jefferson Quote Link to comment Share on other sites More sharing options...
Tezz Posted December 4, 2007 Author Share Posted December 4, 2007 Thanks Shawn that worked first time! The syntax is virtually the same as MADS that I'm using now. It seems I was nearly there with my last attempt, I missed setting my table count with the ldx #5 as it was going through it each vb. you created the label store: ldx #5 which sorted that. Great! I can move on to the next things now that's done. I kept looking at this thinking it must be something simple I'm doing wrong Thanks for your help.. and for everyone else's help also Quote Link to comment Share on other sites More sharing options...
Shawn Jefferson Posted December 5, 2007 Share Posted December 5, 2007 (edited) Yeah, you were nearly there, just needed some tweaking in the logic to make sure that the color regs are set every VBI cycle, and only rotated every X cycles. I didn't change your VBI routine that much, and I'm sure there are ways to optimize it (the other posters are much better at that than I!.) Took me a bit to figure out exactly what you were trying to do though! I originally thought it was something more complex. PS. I just noticed that I put the color table (ctab) into the .rodata segment, and then proceed to change it! Doh! Anyone attempting to use my code to learn should just imagine I meant the .data segment instead. Edited December 5, 2007 by Shawn Jefferson Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.