[Coco] Help with speeding up sprite rendering

Glen Hewlett glen.hewlett at sympatico.ca
Fri Mar 17 15:35:34 EDT 2017


Thanks All for the advice,

Arthur, Walter and William you are absolutely correct I should have thought to disable the interrupts…  I was just at that point at 2am where I was fighting and getting nowhere with my code and I was hopeful someone with a clearer perspective would be able to offer some help.

Also Walter I’m using a 6809 so no extra registers, but thanks for that idea.  :)

William, thanks also for the extra info about the interrupts, trying to learn how they work is one of the reasons I ported Space Invaders to the CoCo3  and why I’m currently working on Pac Man.

I do have a five 16x16 pixel sprites to move around the screen and I need them to be drawn as fast as I can to simulate the dedicated sprite hardware built into the arcade version of Pac Man since it’s dedicated hardware in the original Pac Man I loose quite a bit of 6809 CPU time to drawing the sprites that the Z80 didn’t have to deal with.

Using all the registers for the PULL/PUSH sprite routine including handling the interrupts and restoring them takes 455 CPU cycles (x 5 sprites thats a total of 2,275 cycles).   Using less registers means having two PULL and PUSH instructions per row of the sprite which means the same routine takes 608 CPU cycles (x 5 sprites thats a total of 3,040 cycles).  Using all the registers is 25% faster!  I’m only redrawing 14 rows for my sprites since the top and bottom rows don’t have any data, if I had more rows to copy the savings in CPU time would be even greater.

I just did a small test of my code and it now works!  :)

Cheers,
Glen

Just in case someone else needs this in the future to look at this is part of my code to copy the sprite data to the screen:

This will be different for others since they might have different interrupts being used.  I’m only using the IRQ and not the FIRQ for my code to function as per below.

The code below doesn’t work on the latest MAME (0.183) but it does work on a real CoCo3.  I have a feeling that MAME doesn’t handle turning off all the interrupts very well.  Maybe it’s me, I’ll have to investigate this more as I’ve been using MAME to test my code for the last six months and this is the first time I’ve had an issue with it.

* This is being used on a 256x225 16 colour graphics mode each byte has two pixels of data.  The  LEAU 128+8,U  is to move the U pointer to the next row (256/2=128)
* S points to the Sprite source data (predawn  to be pulled from the stack)
* U points to the Sprite destination memory location

        LDA     #%01001100              *
        STA     $FF90                   * CoCo 3 Mode, MMU Enabled, GIME IRQ Disabled, GIME FIRQ Disabled, Vector RAM at FEXX enabled, Standard SCS Normal, ROM Map 16k Int, 16k
        LDA     #%00000000              * $00 - disable all interrupts
        STA     $FF92                   * Disable all Interrupts
        TFR     CC,B                    * Save the DP since we are going to wipe it below
        STB     Misc02

        TFR     DP,B                    * Save the DP since we are going to wipe it below
        STB     >Misc01                 * restore DP later
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC
        LEAU    128+8,U
        PULS    A,B,X,Y,DP,CC
        PSHU    A,B,X,Y,DP,CC        * Only draw 14 rows, the top and bottom row is blank
        LDB     >Misc01
        TFR     B,DP                * restore the DP

        LDB     Misc02              * Restore the CC register
        TFR     B,CC
        LDA     #%01101100          *
        STA     $FF90               * CoCo 3 Mode, MMU Enabled, GIME IRQ Enabled, GIME FIRQ Disabled, Vector RAM at FEXX enabled, Standard SCS Normal, ROM Map 16k Int, 16k
        LDA     #%00001000          * $08
        STA     $FF92               * Enable only the Vertical Border Sync (VBORD) Interrupt




> On Mar 17, 2017, at 10:32 AM, William Astle <lost at l-w.ca> wrote:
> 
> A couple of points:
> 
> First, "andcc #0" does not disable interrupts. It actually enables them. You need "orcc #$50" to disable interrupts. (That disables both IRQ and FIRQ.)
> 
> Second, as others have noted, as soon as the PULS runs, you're changing the value of CC which might enable the interrupts again. Thus, you have to arrange for no interrupts to be possible while you're doing this.
> 
> Depending on how you have the system set up, that could mean simply disabling the IRQ and FIRQ in the GIME (clearing the enable bits in FF90) or clearing the interrupt enable bits in the PIAs or both. Since IRQ and FIRQ are level triggered, disabling the interrupt sources should clear any pending interrupt.
> 
> Also, you definitely want to disable interrupts anyway when doing the stack trick because you've repurposed S and you definitely don't want an IRQ firing while S is not pointing at a proper stack location - it could trash your sprite data. Also, since you're messing with DP, if your interrupt routine depends on its value, you could have even more excitement.
> 
> Also, there is nothing magical about running during an interrupt service routine. When the IRQ routine starts, CC will have the IRQ bit set (meaning IRQs are masked). (When FIRQ starts, both I and F are set, masking both IRQ and FIRQ.) The "RTI" at the end restores the original CC value. There is no hardware handshake anywhere that prevents interrupts between interrupt service starting and RTI so you don't even need to bother with RTI if you're doing something really clever. Your problems using CC are purely down to the IRQ/FIRQ mask flags getting messed with.
> 
> Finally, given the complexity of dealing with interrupt sources, it might not be worth the confusion to try to use CC. If you move around enough sprites all at once, it might be a win, though. You have to balance that with the cost of turning off the interrupt sources, then turning them on again.
> 
> On 2017-03-17 12:03 AM, Glen Hewlett wrote:
>> Hi All,
>> 
>> I’m working on some routines to draw sprites on the screen faster and I have a lot of it working fine.
>> If I use PULS and PSHU commands I can really improve the speed of my sprite rendering.
>> 
>> For example instead of using a bunch of
>> LDD		,X++
>> STD		,U++
>> ...
>> I’m using
>> PULS	A,B,X,Y,DP
>> PSHU	A,B,X,Y,DP
>>>> 
>> That’s all great for sprites that are 7 bytes wide, but I also need to move sprites that are 8 bytes wide.  I’ve read on the net about using the condition code (CC) in the same way I described above but it breaks my program.  I couldn’t find some example code, just some talk about doing it.
>> 
>> I’ve tried:
>> ANDCC	#$00
>> PULS	A,B,X,Y,DP,CC
>> PSHU	A,B,X,Y,DP,CC
>>>> ANDCC	#$EF	- re-enable the IRQ
>> 
>> I’m not sure what this is doing, as the computer is still running and the IRQ is triggering but it’s not generating the sprites when I do this.  In fact the computer seems to be stuck in the IRQ loop.
>> 
>> Normally my program is moving the sprites around while in the IRQ routine, is this the part of the problem when using the CC register?  Or am I just handling the CC register improperly?
>> 
>> If anyone has some sample code or can offer some advice I sure would appreciate it.
>> 
>> Cheers,
>> Glen.
>> 
> 
> 
> -- 
> Coco mailing list
> Coco at maltedmedia.com
> https://pairlist5.pair.net/mailman/listinfo/coco



More information about the Coco mailing list