First I have to give a big thanks to Mark McDougall who explained to me that I don’t have to have the video ram in the main 64k of addressable space the CoCo3 uses! I should have realized this myself since working on the scrolling routines many times my code would scroll past the screen and view other RAM on the screen. Also Super Disk Extended Basic uses a different memory block for it’s HIRES screens. But it wouldn’t have come to me without someone like Mark telling me. This frees up a good $5000 bytes of RAM which will hopefully allow me to add sound to the game which I really need to learn to do. 🙂

I now setup the videoRAM in the 512k CoCo3 memory banks 0-4 and a backup videoRAM area at $10-$14. This allows me to stop (most) of the flickering when rendering Pac man and the ghosts. For now it simply saves the background of the sprite from the backup videoRAM area, then draws the sprite on the real VideoRAM area. After the next VBLANK it restores the sprite location with the saved background and starts again. This will make the sprites flicker when they cross paths since it doesn’t handle the sprites on top of each other but it’s faster then double buffering and it will do for now.

I will move on from the sprite stuff and get back to transcoding. There is still a little glitch in the speed of the ghosts in the attract animation which I still have to figure out. Then I’ll move on to the demo screen showing the maze and the game in action. But that requires a lot more transcoding… I can work on fixing the video glitches as I go.

Here’s a picture of the first attract mode

I wanted to talk a little bit more about the sprite engine I wrote. It is very optimized now…

This is used for copying the background before the sprite is drawn and also for restoring the background.

Instead of using LOAD and STORE instructions copying data from the background to a temporary buffer the stack is used to PULL the memory to the registers and PUSH them into a temporary location. Since there is no LOAD instructions or STORE instructions this is done very fast. All that is needed is to point the U stack to a storage buffer memory location and point the S stack register to the row in memory that needs to backed up and give it a PULS A,B,X,Y and PSHU A,B,X,Y then move the S pointer to the next line and so on. When it’s done the data in the storage buffer can be used in reverse, it can be PULLED from the stack and stored back into video RAM as quickly as possible on the next restore routine. See the sample code below, it includes the new memory swapping I had to add since I moved the videoRAM blocks around. So it is basically BackupSprite, DrawSprite (not shown below) then next VBLANK RestoreSprite and repeat.

*************************************************************
* BackupSprite:
* Backup the data behind where the Sprite will be placed from the backup VideoRAM Map
* A = Horiztonal (X) pixel location (0 to 239 (255 - 16 "sprite size")) 0 is the left, 255 is the right
* B = Vertical (Y) pixel location (0 to 271 (287 - 16 "sprite size")) 0 is the top, 287 is the bottom
* U = Pointer to the Sprite Location & Stack storage location
*************************************************************
* -5,U = Destination in Video RAM
* -3,U = Even Flag
* -2,U = X & Y
***********************************
BackupSprite:
* Should only be called during the IRQ so no need to do an ORCC #$50
PSHS U
CLR -3,U * Clr Even Flag for this sprite
STD -2,U * Store the X & Y values so it can be checked for collisions with other sprites
BITA #1
BEQ >
INC -3,U * Even # so set Even flag to 1
! RORA * A divided by 2 (screen X is 128 Bytes across from the X 256 pixel value)
LDX #Screen_Start
LEAX A,X
LDA #128 * 128 bytes per row this moves us down in the Y direction
MUL
LEAX D,X * X = Destination location in Video RAM, save and use again for drawing the sprite
STX -5,U * Save the Destination in Video RAM associated with this sprite so it can be automatically restored in the restore sprite routine
STS S_Temp * Save the stack so we can restore it once done
LEAU 145,U * Backup to the temp stack storage then organize it to optimize restore time
* Move U to point to the the end of the Sprite Stack space +1 (PSHS to stack skips the current byte and counts down)
TFR X,D * Calculate which two memory blocks to get for the backup data (from the backup VideoRAM)
CLRB * Clear the Carry flag
ANDA #$E0
RORA * Shift A to the right 5 times to get the block that will hold the backup background
RORA
RORA
RORA
RORA
ADDA #$10 * Backup VideoRAM is between $10 to $14
STA MMU_Reg_5 * $10 to $14
INCA
STA MMU_Reg_6 * $11 to $15
TFR X,D
ANDA #$1F
ADDD #$A000
TFR D,S
PULS A,B,X,Y * Start copying the area behind where the sprite will be from the top left corner
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LEAS 119,S
PULS A,B,X,Y
PSHU A,B,X,Y
PULS A,X
PSHU A,X
LDS S_Temp
PULS U,PC
*************************************************************
* RestoreSprite
* Restore a 16 Bit sprite
* Not needed X - From stored location = Horiztonal pixel location (0 to 239 (255 - 16 "sprite size")) 0 is the left, 255 is the right
* Not Needed Y - From stored location = Vertical pixel location (0 to 271 (287 - 16 "sprite size")) 0 is the top, 287 is the bottom
* U = Pointer to the Sprite storage stack location with Data to be restored
*************************************************************
RestoreSprite:
PSHS U
LDX -5,U * X Now points to the top left location where to restore Video RAM
STS S_Temp * Save the Stack
TFR U,S
TFR X,D * Calculate which two memory blocks to get to restore the backup data to the real VideoRAM
CLRB * Clear the Carry flag
ANDA #$E0
RORA * Shift A to the right 5 times to get the block that will hold our character
RORA
RORA
RORA
RORA
STA MMU_Reg_5 * 0 to 4
INCA
STA MMU_Reg_6 * 1 to 5
TFR X,D
ANDA #$1F
ADDD #$A000
TFR D,X
LEAU 2048-128+9,X * Move U to the bottom right corner of our Sprite restore location
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LEAU -119,U
PULS A,X
PSHU A,X
PULS A,B,X,Y * PULS A,B,X,Y
PSHU A,B,X,Y * PSHU A,B,X,Y
LDS S_Temp
PULS U,PC