The 8-Bit Guy 105 Posted February 2 During my conversion of Petscii Robots over to the X16, it was relatively smooth until I added sound support. So, I thought I'd talk about the one big issue I ran into, which I wasn't expecting due to my previous experience coding for Commodore machines. Because the Vera has it's own video RAM, you have to set the VERA_L, VERA_M, and VERA_H every time you are about to write something to video RAM. It's a little more cumbersome than the way things are done on other Commodore computers, but not terribly so. In fact, in about 25% of cases, I found it easier to use this than the C64, depending on what I was trying to modify on the screen. So, In my sound/music routine, I'm using the VERA's built-in PSG. Which means my sound routine is changing VERA_L, VERA_M, and VERA_H every time the IRQ routine runs. And the IRQ can run right in the middle of your writes to VRAM. And unless you want to add an SEI and CLI before and after every routine that writes data to VRAM, you'll need to backup the VERA address registers in your IRQ routine. So, I did this: LDA VERA_H PHA LDA VERA_M PHA LDA VERA_L PHA ***insert IRQ code here *** PLA STA VERA_L PLA STA VERA_M PLA STA VERA_H Now, while this may sound obvious to some people, I wasn't accustomed to dealing with this sort of thing when writing to sound registers in the SID or VIC-20 or whatever, since they were their own separate registers. Anyway, hopefully this piece of advice will help somebody else not pull their hair out in the future. 9 4 Quote Share this post Link to post Share on other sites
Guybrush 22 Posted February 2 You could possibly set your code up in such a way that VRAM access uses port 1 and sound register access uses port 2. 3 Quote Share this post Link to post Share on other sites
VincentF 38 Posted February 2 Had this exact same problem and this exact same solution just yesterday Quote Share this post Link to post Share on other sites
JimmyDansbo 141 Posted February 2 (edited) I ran into the same issue (and solution) when I created the IRQclock program... https://github.com/JimmyDansbo/cx16stuff/blob/master/irclock.asm#L109 Edited February 2 by JimmyDansbo Quote Share this post Link to post Share on other sites
TomXP411 318 Posted February 2 Funny... I was just thinking about this yesterday, as well... but from a different perspective. Someone was talking about using conio commands in C, and it occurred to me that ISRs (interrupt service routine) might write to VERA while you're in the middle of another process. So I guess it's doubly important to make sure interrupt handlers always back up the VERA registers before making any changes - not just for their own use, but to protect running software and protect the transparency of ISRs. Quote Share this post Link to post Share on other sites
m00dawg 111 Posted February 2 47 minutes ago, Guybrush said: You could possibly set your code up in such a way that VRAM access uses port 1 and sound register access uses port 2. This is what I decided to do, although I'm not sure this would completely solve it in all cases. It's solved it for me - so far anyway. Of note, VERA PSG does require a lot of CPU support to make chippy sounds (due to software envelopes) so I can see communicating with VERA to be a very common occurrence as a result. Quote Share this post Link to post Share on other sites
The 8-Bit Guy 105 Posted February 2 1 hour ago, Guybrush said: You could possibly set your code up in such a way that VRAM access uses port 1 and sound register access uses port 2. Excellent idea. I hadn't considered this. It would still require changing the data port before and after the IRQ runs, but that's probably less code and CPU cycles than backing up the registers. 1 Quote Share this post Link to post Share on other sites
Guybrush 22 Posted February 2 17 minutes ago, The 8-Bit Guy said: Excellent idea. I hadn't considered this. It would still require changing the data port before and after the IRQ runs, but that's probably less code and CPU cycles than backing up the registers. It would only require changing the CTRL register's ADDRSEL bit to set the active port while reloading the address registers but that's just one register instead of three. If you don't use any of the KERNAL's graphics functions then you have complete control of the VERA and you can be sure that nothing else is touching the address registers and the CTRL register. Then you can simply do LDA #$01, ORA $9f29 when you enter the interrupt handler and LDA #$FE, AND $9f29 before exiting. That's just 12 cycles instead of 15 when using the stack. I know that's not that important on Commander X16 compared to C64, but I just can't help myself . Quote Share this post Link to post Share on other sites
Greg King 57 Posted February 2 48 minutes ago, Guybrush said: It would only require changing the CTRL register's ADDRSEL bit to set the active port while reloading the address registers, but that's just one register instead of three. If you don't use any of the KERNAL's graphics functions, then you have complete control of the VERA, and you can be sure that nothing else is touching the address registers and the CTRL register. Then, you can simply do LDA #$01, ORA $9f29 when you enter the interrupt handler, and LDA #$FE, AND $9f29 before exiting. That's just 12 cycles instead of 15 when using the stack. I know that's not that important on Commander X16 compared to C64, but I just can't help myself . You don't need even that much. Just do "inc $9F25" when starting the ISR. And, "stz $9F25" when leaving the ISR. (The DCSEL bit is irrelevant.) 1 Quote Share this post Link to post Share on other sites
DusanStrakl 96 Posted February 3 Yup had the same problem when I wrote music library for BASIC programs. Of course I had to back up registers because I had to allow the default IRQ handler to take over after I was done playing with PSG (pun intended ) and of course BASIC programs print, draw, scroll, etc. Quote Share this post Link to post Share on other sites
AndyMt 140 Posted February 3 18 hours ago, The 8-Bit Guy said: And the IRQ can run right in the middle of your writes to VRAM. Ah - this is why the sound effects in Invaderz sometimes drop out or chip in some way... I can now fix this, thanks a lot! 2 Quote Share this post Link to post Share on other sites
StephenHorn 292 Posted February 3 My solution to this was to generally run all of my logic in the IRQ, starting with screen draws, while the non-interrupt code essentially spins on a tight loop checking on a single memory address. This way I don't have to worry about any of my routines being interrupted. An additional up-side to this is that I effectively have a thread that's not doing anything, and I'm thinking it would be ideal to place my streaming I/O logic into there, essentially spinning through banks and loading files as needed into them. In particular, I really like the VERA's dual access channels and auto-increment settings, and how they make it really easy to write columns and rows of 16-bit tile data. Quote Share this post Link to post Share on other sites
paulscottrobson 36 Posted February 3 Might be quicker to semaphore it, so when your code isn't updating Vera you don't have to execute the code if it hasn't claimed the semaphore. Really depends :) There's an argument that you shouldn't update in IRQ anyway, but have a Model-View design, so you update your model if you want in the interrupt routine, just using the IRQ as a timer. Quote Share this post Link to post Share on other sites