Switching a cog from WAITATN triggered to ATTENTION INTERRUPT triggered
Rayman
Posts: 14,646
This looks to be more straightforward than I thought, but with a twist.
One cog in my tile driver has the simple task of swapping out colors in the LUT so that each tile can have its own set of colors.
So, there are three nested loops, one for the screen, one for the tile row, and one for the rows within the tile.
In the middle of these loops is a WAITATN where it waits for the vga driver to tell it to update the LUT.
This is all fine, but this cog is severely underutilized.
I'd like to switch it over to being interrupt driven, so that it can do other things (like Graphics).
Anyway, this was really easy to do!
In the middle of these nested loops, just before the WAITATN, I dropped this in:
Added one new register, c7, as a flag to say if this is the first time in the loop or not.
What surprised me is that I still needed the WAITATN.
I expected that to be cleared by the interrupt, but seems it was not...
One cog in my tile driver has the simple task of swapping out colors in the LUT so that each tile can have its own set of colors.
So, there are three nested loops, one for the screen, one for the tile row, and one for the rows within the tile.
In the middle of these loops is a WAITATN where it waits for the vga driver to tell it to update the LUT.
This is all fine, but this cog is severely underutilized.
I'd like to switch it over to being interrupt driven, so that it can do other things (like Graphics).
Anyway, this was really easy to do!
In the middle of these nested loops, just before the WAITATN, I dropped this in:
...Start of nested loops 'New Interrupt Section Starts------------------------------------------------------ 'This is where we can stop and let interrupt take over cmp c7,#0 wcz 'is interrupt enabled (non-zero)? ColorInterruptOnly if_nz RETI3 'if this is not the first time here, we are done, return 'If still here, this is the first time through the loop 'Configure interrupt to go to ColorSetLoop mov IJMP3,#ColorSetLoop 'this is where we used to wait for attention SETINT3 #14 'set interrupt to trigger on attention mov c7,#1 'note to self that this is not our first time in the loop and interrupts are enabled. CStop jmp #CStop 'for now, just do nothing except respond to ISR 'New Interrupt Section Ends------------------------------------------------------ ColorSetLoop 'Note: Rev.2e: Reversing order of LUT writes. 3,2,1,0 instead of 0,1,2,3 ' This will get the fbfb, ffbb order for selecting even/odd 2bpp characters be same as P1 waitatn '<---- This is where we used to wait for attention ...Start of color code within nested loops
Added one new register, c7, as a flag to say if this is the first time in the loop or not.
What surprised me is that I still needed the WAITATN.
I expected that to be cleared by the interrupt, but seems it was not...
Comments
On the other side, unintuitive interactions can crop up with smartpins as event sources too. But once you've mentally stepped through it, it makes sense.
PS: I suspect using a GETINT to log the IRQ state on either side of POLLATN will show you the change of state in the events.
But, this ISR only gets called when ATN is given. So, I think it doesn't actually wait at WAITATN. It just clears the ATN flag...
But, I tried just changing waitatn to pollatn and it doesn't work...
Seems like it should...
It seems like, then, the ATN didn't happen, yet, and it needed to be waited for. If that's the case, I wonder for how long?
waitatn clears it but pollatn doesn't?
Maybe this shows it's not the compiler:
I went back to a previous version without interrupt and tried using pollatn like this:
With the pollatn part uncommented and the waitatn and nops commented out, it sorta works but the timing is way off.
I put in these nops to check if a slight delay makes a difference and it doesn't.
It appears as if polling has a very long delay associated with it compared with waiting...