Game loops and Vertical Blank interupts
Moderator: BigEvilCorporation
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Re: Game loops and Vertical Blank interupts
You also need some protection around that code in the vblank to keep from getting recursion in the vblank int. Set a flag before changing the sr, and in the vblank routine, just do the dma and exit if the flag is set. The code after the game loop should clear the flag.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
Re: Game loops and Vertical Blank interupts
Ah yeah indeed you should keep track you are inside the vint handler to avoid recursion if your vint code take more than one frame...
Re: Game loops and Vertical Blank interupts
When you are INSIDE an exception, can you attend another exception of the same priority (vint) or lower (hint)? I thought no, but maybe I'm mistaken... Let me search for it...
edit:
Ok! yes! interrupt priority mask is set to 6 inside vertical exception, so if I lower it to 3 again it will be able to attend more exceptions without doing a "rte", is that what do you mean ?
That simplifies things!
HELP. Spanish TVs are brain washing people to be hostile to me.
Re: Game loops and Vertical Blank interupts
It works! thanks Stef!
New version:
New version:
Code: Select all
reset:
jsr initialization
jmp backgroundTasks
vertException:
tst.b gameState
jeq 0f
addq.w #1, framesLost
rte
0:
movem.l %d?/%a?, -(%sp)
jsr doDMAThings
move.b #1, gameState
move.w #0x2300, %sr /* enable exceptions */
jsr gameLoop
movem.l (%sp)+,%d?/%a?
move.b #0, gameState
rte
Correct! I already said that. Hope the new code suits you.Chilly Willy wrote: ↑Tue May 15, 2018 1:54 amYou also need some protection around that code in the vblank to keep from getting recursion in the vblank int. Set a flag before changing the sr, and in the vblank routine, just do the dma and exit if the flag is set. The code after the game loop should clear the flag.
HELP. Spanish TVs are brain washing people to be hostile to me.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
Re: Game loops and Vertical Blank interupts
You made it in a brutal way (moving 0x23 directly to SR) but yeah that was the idea
Also you can test gameState after the DMA processing (as it should never be set before).
Also you can test gameState after the DMA processing (as it should never be set before).
Re: Game loops and Vertical Blank interupts
Which fields/flags you think worth of preserving? At this precise point condition codes (Z,X,...) are not useful at all and all the other ones I set them as I want to be.
I disagree. You can't allow DMA jobs to be launched at any time because the data could be malformed (the exception can be launched when you are setting the data).
Perhaps if you could make the code in a way that only one instruction makes the difference between a job is fully queued or not...
Another problem is you will be updating only partially a frame... could be visual artefacts...
HELP. Spanish TVs are brain washing people to be hostile to me.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
Re: Game loops and Vertical Blank interupts
Well, just for security i would always prefer to just modify interrupt mask level part of register but indeed using 0x2300 should definitely not hurt hereMiquel wrote: Which fields/flags you think worth of preserving? At this precise point condition codes (Z,X,...) are not useful at all and all the other ones I set them as I want to be.
Well it's all up to your game logic. I guess the doDMAJobs(..) method use kind of DMA queue system. If only gameLoop actually queues data for DMA there is no use in separating them but if your main background loop is also queuing data then DMA should always happen here (or you will loss some precious DMA bandwidth).Miquel wrote: I disagree. You can't allow DMA jobs to be launched at any time because the data could be malformed (the exception can be launched when you are setting the data).
Perhaps if you could make the code in a way that only one instruction makes the difference between a job is fully queued or not...
Another problem is you will be updating only partially a frame... could be visual artefacts...
Re: Game loops and Vertical Blank interupts
Queuing DMA jobs from the background "thread", that's really the problem!
I particularly use a buffer to queue commands and data to the vertical "thread". But I think I just have found a solution: use a MOVEM to fill that buffer all at once.
The only problem is, to perform DMA operation you need to set 7 registers, this way it will be setting 8... I need a trouble free writing to 0x00C00004... I think I could set any register to any value except the one that fires the dma...
I particularly use a buffer to queue commands and data to the vertical "thread". But I think I just have found a solution: use a MOVEM to fill that buffer all at once.
The only problem is, to perform DMA operation you need to set 7 registers, this way it will be setting 8... I need a trouble free writing to 0x00C00004... I think I could set any register to any value except the one that fires the dma...
HELP. Spanish TVs are brain washing people to be hostile to me.
Re: Game loops and Vertical Blank interupts
Throw autoincrement into the mix. Usually you'd use 2, but if you want to write vertically to a tilemap you may want to use 128 (assuming 64×32 or 64×64), and for the horizontal scroll table you may want to use 4 so you can keep each plane separate in your buffers in RAM. And possibly some other uses. That should pad it out to eight words and provide an useful feature.
By the way: if you disable an interrupt and it tries to fire while disabled, then it'll fire immediately as soon as you reenable it, no matter how long it has taken to be reenabled. So you could use that as some sort of mutex from the background thread.
By the way: if you disable an interrupt and it tries to fire while disabled, then it'll fire immediately as soon as you reenable it, no matter how long it has taken to be reenabled. So you could use that as some sort of mutex from the background thread.
Sik is pronounced as "seek", not as "sick".
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Re: Game loops and Vertical Blank interupts
Yeah, I was going to mention that any time you write data to a structure (like a queue) that is read from an int, you NEED to disable ints while setting it, not just rely on "indivisible" instructions. Learned a lot about that while working on the Amiga. You don't need to fully disable ints in some cases, just the ones that use the queue. Unfortunately, SEGA got the priorities of the vblank and hblank backwards, so using the vbint means effectively disabling ints while working on critical structs. You could have done a lot more with vbints on the Genny if they had swapped the two priorities, making hblank 6 and vblank 4.
Re: Game loops and Vertical Blank interupts
Disabling the vblank interrupt from the VDP itself (i.e. register $81xx) has the same delaying effect as masking it away with SR (i.e. it's not discarded). So yes, you can disable vblank without disabling hblank.
The implication of the above is that if you're enabling them for the first time then you better get ready to cope with an immediately firing interrupt that shouldn't have been there :v (so make sure to either dummy them out or that their side-effects are not dangerous)
The implication of the above is that if you're enabling them for the first time then you better get ready to cope with an immediately firing interrupt that shouldn't have been there :v (so make sure to either dummy them out or that their side-effects are not dangerous)
Sik is pronounced as "seek", not as "sick".
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Re: Game loops and Vertical Blank interupts
That's probably the better way to handle it if you use hblank ints, then.Sik wrote: ↑Thu May 17, 2018 2:30 pmDisabling the vblank interrupt from the VDP itself (i.e. register $81xx) has the same delaying effect as masking it away with SR (i.e. it's not discarded). So yes, you can disable vblank without disabling hblank.
The implication of the above is that if you're enabling them for the first time then you better get ready to cope with an immediately firing interrupt that shouldn't have been there :v (so make sure to either dummy them out or that their side-effects are not dangerous)
Re: Game loops and Vertical Blank interupts
In theory, after reading some documentation on Internet, the second group of interruptions, were vint and hint belong fires only after the finalization of the current instruction. So if you can queue with only one instruction you don't need to disable interrupts.Chilly Willy wrote: ↑Thu May 17, 2018 1:21 pmYeah, I was going to mention that any time you write data to a structure (like a queue) that is read from an int, you NEED to disable ints while setting it, not just rely on "indivisible" instructions. Learned a lot about that while working on the Amiga. You don't need to fully disable ints in some cases, just the ones that use the queue.
But in my case I also need to update a "pointer to next position", so that's what I ended up doing:
Code: Select all
move.w #0x2700, %sr /* disable exceptions */
move.l pVideoBufferPos, %a0
movem.l %d0-%d5, (%a0) /* copy data to buffer */
lea 20(%a0), %a0
move.l %a0, pVideoBufferPos
move.w #0x2300, %sr /* enable exceptions */
HELP. Spanish TVs are brain washing people to be hostile to me.
Re: Game loops and Vertical Blank interupts
One thing a lot of NES games do is set a variable to $00 until VBlank has fired, and then during VBlank, it gets set to $FF. At the end of VBlank, it returns to $00. This could be easily adapted to the Sega Genesis.
This could be checked for at the beginning of the VBlank routine: If the flag is $00, make it $FF and run VBlank code. If the flag is $FF, immediately jump to the RTE (restoring registers if you saved them).
This could be checked for at the beginning of the VBlank routine: If the flag is $00, make it $FF and run VBlank code. If the flag is $FF, immediately jump to the RTE (restoring registers if you saved them).
When programming, you can do it if you put your mind to it.
Re: Game loops and Vertical Blank interupts
Unless I misunderstand you that's more or less how my last example works, or how SGDK works.
Since 68K has bit specialized instructions could be better to just use a bit of a variable.
Since 68K has bit specialized instructions could be better to just use a bit of a variable.
HELP. Spanish TVs are brain washing people to be hostile to me.