This build has the player moving in X and Y directions and with cleaner handling of the dirty tile to remove the inefficiencies. The good news is that there is no longer any performance problem at 2.8 MHz now that the inefficient dirty tile handling has been removed. The bad news is that they player leaves garbage behind indicating some kind of problem with dirty tile marking. But it is close.

This commit is contained in:
Jeremy Rand 2020-11-05 00:21:46 -05:00
parent bb66ef4b03
commit edcddc0bd8
5 changed files with 129 additions and 72 deletions

View File

@ -78,7 +78,7 @@
9D33970024AEFBF2003222B3 /* segments.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = segments.s; sourceTree = "<group>"; }; 9D33970024AEFBF2003222B3 /* segments.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = segments.s; sourceTree = "<group>"; };
9D33970124AF9D55003222B3 /* sprites.macros */ = {isa = PBXFileReference; lastKnownFileType = text; path = sprites.macros; sourceTree = "<group>"; }; 9D33970124AF9D55003222B3 /* sprites.macros */ = {isa = PBXFileReference; lastKnownFileType = text; path = sprites.macros; sourceTree = "<group>"; };
9D47CBE02547BEDB00CDA5CB /* gameMushroom.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameMushroom.s; sourceTree = "<group>"; }; 9D47CBE02547BEDB00CDA5CB /* gameMushroom.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameMushroom.s; sourceTree = "<group>"; };
9D47CC14254A698900CDA5CB /* gamePlayer.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamePlayer.s; sourceTree = "<group>"; }; 9D47CC14254A698900CDA5CB /* gamePlayer.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamePlayer.s; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.asm.orcam; };
9D47CCBA25525C1A00CDA5CB /* tileData.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = tileData.pl; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; }; 9D47CCBA25525C1A00CDA5CB /* tileData.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = tileData.pl; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
9D62AF3B249871A300348F45 /* colour.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = colour.s; sourceTree = "<group>"; }; 9D62AF3B249871A300348F45 /* colour.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = colour.s; sourceTree = "<group>"; };
9D62AF3F2499CD1E00348F45 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; 9D62AF3F2499CD1E00348F45 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };

View File

@ -122,7 +122,7 @@ $(GENDIR)/tileData.s: tileData.pl Makefile
# add rules in genclean to remove those generated files when you # add rules in genclean to remove those generated files when you
# clean your build. # clean your build.
genclean: genclean:
$(RM) $(GENDIR)/tileData.s $(GENDIR)/tileData.h $(RM) $(GENDIR)/tileData.s $(GENDIR)/screenData.s $(GENDIR)/tileData.h
# Do not change anything else below here... # Do not change anything else below here...
include make/tail.mk include make/tail.mk

View File

@ -13,14 +13,7 @@
gamePlayer start gamePlayer start
using globalData using globalData
using tileData using tileData
using screenData
PLAYER_TILES_HIGH equ 7
MOUSE_MAX_X equ GAME_NUM_TILES_WIDE*TILE_PIXEL_WIDTH-TILE_PIXEL_WIDTH
MOUSE_MAX_Y equ GAME_NUM_TILES_TALL*TILE_PIXEL_HEIGHT-TILE_PIXEL_HEIGHT
STARTING_MOUSE_X equ GAME_NUM_TILES_WIDE*TILE_PIXEL_WIDTH/2
STARTING_MOUSE_Y equ MOUSE_MAX_Y
initPlayer entry initPlayer entry
lda #STARTING_MOUSE_X lda #STARTING_MOUSE_X
@ -110,51 +103,51 @@ updatePlayer_doneY anop
sta mouseDown sta mouseDown
updatePlayer_skipDeltas anop updatePlayer_skipDeltas anop
lda mouseY
asl a
tay
lda mouseX lda mouseX
lsr a lsr a
bcs updatePlayer_shift bcs updatePlayer_shift
adc #$9834 adc mouseYAddress,y
sta mouseAddress
tay tay
jsl drawShip jsl drawShip
bra updatePlayer_dirty bra updatePlayer_dirty
updatePlayer_shift anop updatePlayer_shift anop
adc #$9833 adc mouseYAddress,y
sta mouseAddress
dec a
tay tay
jsl drawShipShift jsl drawShipShift
bra updatePlayer_dirty bra updatePlayer_dirty
updatePlayer_dirty anop updatePlayer_dirty anop
lda mouseAddress
sec
sbc #SCREEN_ADDRESS
and #$fff8
tax
lda >screenToTileOffset,x
tax
lda #TILE_STATE_DIRTY lda #TILE_STATE_DIRTY
sta tileDirty+1200 sta tileDirty,x
sta tileDirty+1202 ldy tileRight,x
sta tileDirty+1204 sta tileDirty,y
sta tileDirty+1206 ldy tileBelow,x
sta tileDirty+1208 cpy #INVALID_TILE_NUM
sta tileDirty+1210 beq updatePlayer_done
sta tileDirty+1212 sta tileDirty,y
sta tileDirty+1214 ldx tileRight,y
sta tileDirty+1216 sta tileDirty,x
sta tileDirty+1218
sta tileDirty+1220 updatePlayer_done anop
sta tileDirty+1222
sta tileDirty+1224
sta tileDirty+1226
sta tileDirty+1228
sta tileDirty+1230
sta tileDirty+1232
sta tileDirty+1234
sta tileDirty+1236
sta tileDirty+1238
sta tileDirty+1240
sta tileDirty+1242
sta tileDirty+1244
sta tileDirty+1246
sta tileDirty+1248
rtl rtl
mouseX dc i2'0' mouseX dc i2'0'
mouseY dc i2'0' mouseY dc i2'0'
mouseDown dc i2'0' mouseDown dc i2'0'
mouseAddress dc i2'0'
end end

View File

@ -8,7 +8,6 @@ s6d2 =
s7d1 = /Users/jrand/Library/Developer/Xcode/DerivedData/BuGS-bffpexoblaghkzcbtjtzxeulnuto/Build/Products/Debug/BuGS.2mg s7d1 = /Users/jrand/Library/Developer/Xcode/DerivedData/BuGS-bffpexoblaghkzcbtjtzxeulnuto/Build/Products/Debug/BuGS.2mg
g_limit_speed = 3
bram1[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00 bram1[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00

View File

@ -19,7 +19,7 @@ our %gEquates;
# These are global equates which will also become defines in the C header file. Also, these will drive the other # These are global equates which will also become defines in the C header file. Also, these will drive the other
# data that is generated by this script. # data that is generated by this script.
$gEquates{"SCREEN_ADDRESS"} = 0x2000;
$gEquates{"SCREEN_PIXELS_WIDE"} = 320; $gEquates{"SCREEN_PIXELS_WIDE"} = 320;
$gEquates{"SCREEN_PIXELS_TALL"} = 200; $gEquates{"SCREEN_PIXELS_TALL"} = 200;
$gEquates{"SCREEN_PIXELS_PER_BYTE"} = 2; $gEquates{"SCREEN_PIXELS_PER_BYTE"} = 2;
@ -55,6 +55,12 @@ $gEquates{"SPIDER_MAX_NUM_POSSIBLE_ROWS"} = 10;
$gEquates{"SPIDER_STARTING_TOP_ROW"} = $gEquates{"GAME_NUM_TILES_TALL"} - $gEquates{"SPIDER_MAX_NUM_POSSIBLE_ROWS"}; $gEquates{"SPIDER_STARTING_TOP_ROW"} = $gEquates{"GAME_NUM_TILES_TALL"} - $gEquates{"SPIDER_MAX_NUM_POSSIBLE_ROWS"};
$gEquates{"SPIDER_STARTING_TOP_ROW_OFFSET"} = $gEquates{"SPIDER_STARTING_TOP_ROW"} * $gEquates{"GAME_NUM_TILES_WIDE"} * $gEquates{"SIZEOF_TILE_INFO"}; $gEquates{"SPIDER_STARTING_TOP_ROW_OFFSET"} = $gEquates{"SPIDER_STARTING_TOP_ROW"} * $gEquates{"GAME_NUM_TILES_WIDE"} * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"PLAYER_TILES_HIGH"} = 7;
$gEquates{"MOUSE_MAX_X"} = (($gEquates{"GAME_NUM_TILES_WIDE"} - 1) * $gEquates{"TILE_PIXEL_WIDTH"}) + 1;
$gEquates{"MOUSE_MAX_Y"} = (($gEquates{"PLAYER_TILES_HIGH"} - 1) * $gEquates{"TILE_PIXEL_HEIGHT"}) + 1;
$gEquates{"STARTING_MOUSE_X"} = $gEquates{"MOUSE_MAX_X"} / 2;
$gEquates{"STARTING_MOUSE_Y"} = $gEquates{"MOUSE_MAX_Y"} - 1;
our @gTileDirty = ("TILE_STATE_CLEAN") x $gEquates{"TOTAL_NUM_TILES"}; our @gTileDirty = ("TILE_STATE_CLEAN") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileScreenOffset = (0) x $gEquates{"TOTAL_NUM_TILES"}; our @gTileScreenOffset = (0) x $gEquates{"TOTAL_NUM_TILES"};
@ -68,20 +74,21 @@ our @gTileBitMask = (0) x $gEquates{"NUM_GAME_TILES"};
our @gDirtyNonGameTiles = ("INVALID_TILE_NUM") x $gEquates{"NUM_NON_GAME_TILES"}; our @gDirtyNonGameTiles = ("INVALID_TILE_NUM") x $gEquates{"NUM_NON_GAME_TILES"};
our $gNumDirtyNonGameTiles = 0; our $gNumDirtyNonGameTiles = 0;
our @gMouseYAddress = (0) x $gEquates{"MOUSE_MAX_Y"};
our @gScreenToTileOffset = (0) x ($gEquates{"SCREEN_PIXELS_TALL"} * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"});
sub printTileData sub printTileData
{ {
my ($symbol, @data) = @_; my ($fh, $symbol, @data) = @_;
print $fh "\n";
print $fh "\n";
print $fh "$symbol anop\n";
print TILEDATA_S << "EOF"; for my $index (0 .. $#data)
$symbol anop
EOF
for my $tileNum (0 .. $#data)
{ {
print TILEDATA_S " dc i2'$data[$tileNum]'\t; Tile number $tileNum\n"; print $fh " dc i2'$data[$index]'\t; Index $index\n";
} }
} }
@ -169,7 +176,7 @@ sub screenAddressForTileAtXY
{ {
my ($x, $y) = @_; my ($x, $y) = @_;
return 0x2000 + ($gEquates{"SCREEN_BYTES_PER_ROW"} * $y) + ($x / $gEquates{"SCREEN_PIXELS_PER_BYTE"}) + 3; return $gEquates{"SCREEN_ADDRESS"} + ($gEquates{"SCREEN_BYTES_PER_ROW"} * $y) + ($x / $gEquates{"SCREEN_PIXELS_PER_BYTE"}) + 3;
} }
@ -181,15 +188,26 @@ sub initTiles
my $bitMask = 1; my $bitMask = 1;
my $rhsTileIndex = $gEquates{"RHS_FIRST_TILE"}; my $rhsTileIndex = $gEquates{"RHS_FIRST_TILE"};
my $lhsTileIndex = $gEquates{"LHS_FIRST_TILE"}; my $lhsTileIndex = $gEquates{"LHS_FIRST_TILE"};
my $screenOffset = 0;
for ($tileY = 0; $tileY < $gEquates{"TOTAL_TILES_TALL"}; $tileY++) for ($tileY = 0; $tileY < $gEquates{"TOTAL_TILES_TALL"}; $tileY++)
{ {
$screenOffset = ($tileY * $gEquates{"TILE_PIXEL_HEIGHT"} * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"});
$lastOffset = screenAddressForTileAtXY(0, $tileY * $gEquates{"TILE_PIXEL_HEIGHT"}); $lastOffset = screenAddressForTileAtXY(0, $tileY * $gEquates{"TILE_PIXEL_HEIGHT"});
for ($tileX = 0; $tileX < $gEquates{"LHS_NUM_TILES_WIDE"}; $tileX++) for ($tileX = 0; $tileX < $gEquates{"LHS_NUM_TILES_WIDE"}; $tileX++)
{ {
$gTileScreenOffset[$lhsTileIndex] = $lastOffset; $gTileScreenOffset[$lhsTileIndex] = $lastOffset;
for (my $word = 0; $word < ($gEquates{"TILE_BYTE_WIDTH"} / $gEquates{"SIZEOF_TILE_INFO"}); $word++)
{
for (my $y = 0; $y < $gEquates{"TILE_PIXEL_HEIGHT"}; $y++)
{
$gScreenToTileOffset[$screenOffset + ($y * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"})] = $lhsTileIndex * $gEquates{"SIZEOF_TILE_INFO"};
}
$screenOffset++;
}
if ($tileY != 0) if ($tileY != 0)
{ {
$gTileAbove[$lhsTileIndex] = lhsXYToTileOffset($tileX, $tileY - 1); $gTileAbove[$lhsTileIndex] = lhsXYToTileOffset($tileX, $tileY - 1);
@ -225,6 +243,15 @@ sub initTiles
$gTileBitOffset[$tileIndex] = $bitOffset; $gTileBitOffset[$tileIndex] = $bitOffset;
$gTileBitMask[$tileIndex] = $bitMask; $gTileBitMask[$tileIndex] = $bitMask;
for (my $word = 0; $word < ($gEquates{"TILE_BYTE_WIDTH"} / $gEquates{"SIZEOF_TILE_INFO"}); $word++)
{
for (my $y = 0; $y < $gEquates{"TILE_PIXEL_HEIGHT"}; $y++)
{
$gScreenToTileOffset[$screenOffset + ($y * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"})] = $tileIndex * $gEquates{"SIZEOF_TILE_INFO"};
}
$screenOffset++;
}
if ($tileY != 0) if ($tileY != 0)
{ {
$gTileAbove[$tileIndex] = gameXYToTileOffset($tileX, $tileY - 1); $gTileAbove[$tileIndex] = gameXYToTileOffset($tileX, $tileY - 1);
@ -272,6 +299,15 @@ sub initTiles
{ {
$gTileScreenOffset[$rhsTileIndex] = $lastOffset; $gTileScreenOffset[$rhsTileIndex] = $lastOffset;
for (my $word = 0; $word < ($gEquates{"TILE_BYTE_WIDTH"} / $gEquates{"SIZEOF_TILE_INFO"}); $word++)
{
for (my $y = 0; $y < $gEquates{"TILE_PIXEL_HEIGHT"}; $y++)
{
$gScreenToTileOffset[$screenOffset + ($y * $gEquates{"SCREEN_BYTES_PER_ROW"} / $gEquates{"SIZEOF_TILE_INFO"})] = $rhsTileIndex * $gEquates{"SIZEOF_TILE_INFO"};
}
$screenOffset++;
}
if ($tileY != 0) if ($tileY != 0)
{ {
$gTileAbove[$rhsTileIndex] = rhsXYToTileOffset($tileX, $tileY - 1); $gTileAbove[$rhsTileIndex] = rhsXYToTileOffset($tileX, $tileY - 1);
@ -301,6 +337,14 @@ sub initTiles
$lastOffset += $gEquates{"TILE_BYTE_WIDTH"}; $lastOffset += $gEquates{"TILE_BYTE_WIDTH"};
} }
} }
# Calculate the memory address of the 0th row of the player's mouse position.
$lastOffset = $gEquates{"SCREEN_ADDRESS"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * $gEquates{"TILE_BYTE_WIDTH"}) + (($gEquates{"GAME_NUM_TILES_TALL"} - $gEquates{"PLAYER_TILES_HIGH"}) * $gEquates{"TILE_PIXEL_HEIGHT"} * $gEquates{"SCREEN_BYTES_PER_ROW"});
for (my $y = 0; $y < $gEquates{"MOUSE_MAX_Y"}; $y++)
{
$gMouseYAddress[$y] = $lastOffset;
$lastOffset += $gEquates{"SCREEN_BYTES_PER_ROW"};
}
} }
@ -381,9 +425,8 @@ initTiles();
initNonGameTiles(); initNonGameTiles();
# Generate the tileData.s file # Generate the tileData.s file
open my $fh, ">", "$gGenDir/tileData.s" or die "$0: Unable to open $gGenDir/tileData.s for writing, $!";
open(TILEDATA_S, "> $gGenDir/tileData.s") or die "$0: Unable to open $gGenDir/tileData.s for writing, $!"; my $text = << "EOF";
print TILEDATA_S << "EOF";
case on case on
mcopy tilesData.macros mcopy tilesData.macros
keep tilesData keep tilesData
@ -392,56 +435,78 @@ tileData data
using globalData using globalData
EOF EOF
print $fh $text;
foreach my $equate (sort keys %gEquates) foreach my $equate (sort keys %gEquates)
{ {
print TILEDATA_S "$equate\tgequ " . $gEquates{$equate} . "\n"; print $fh "$equate\tgequ " . $gEquates{$equate} . "\n";
} }
printTileData("tileDirty", @gTileDirty); printTileData($fh, "tileDirty", @gTileDirty);
printTileData("tileScreenOffset", @gTileScreenOffset); printTileData($fh, "tileScreenOffset", @gTileScreenOffset);
printTileData("tileType", @gTileType); printTileData($fh, "tileType", @gTileType);
printTileData("tileAbove", @gTileAbove); printTileData($fh, "tileAbove", @gTileAbove);
printTileData("tileBelow", @gTileBelow); printTileData($fh, "tileBelow", @gTileBelow);
printTileData("tileLeft", @gTileLeft); printTileData($fh, "tileLeft", @gTileLeft);
printTileData("tileRight", @gTileRight); printTileData($fh, "tileRight", @gTileRight);
printTileData("tileBitOffset", @gTileBitOffset); printTileData($fh, "tileBitOffset", @gTileBitOffset);
printTileData("tileBitMask", @gTileBitMask); printTileData($fh, "tileBitMask", @gTileBitMask);
printTileData("dirtyNonGameTiles", @gDirtyNonGameTiles); printTileData($fh, "dirtyNonGameTiles", @gDirtyNonGameTiles);
printTileData($fh, "mouseYAddress", @gMouseYAddress);
print TILEDATA_S << "EOF"; $text = << "EOF";
numDirtyNonGameTiles dc i2'$gNumDirtyNonGameTiles' numDirtyNonGameTiles dc i2'$gNumDirtyNonGameTiles'
end end
EOF
print $fh $text;
close($fh);
# Generate the screenData.s file
open $fh, ">", "$gGenDir/screenData.s" or die "$0: Unable to open $gGenDir/screenData.s for writing, $!";
$text = << "EOF";
case on
mcopy screenData.macros
keep screenData
screenData data screenDataSeg
EOF EOF
print $fh $text;
close(TILEDATA_S); printTileData($fh, "screenToTileOffset", @gScreenToTileOffset);
$text = << "EOF";
end
EOF
print $fh $text;
close($fh);
# Generate the tileData.h file # Generate the tileData.h file
open(TILEDATA_H, "> $gGenDir/tileData.h") or die "$0: Unable to open $gGenDir/tileData.h for writing, $!"; open $fh, ">", "$gGenDir/tileData.h" or die "$0: Unable to open $gGenDir/tileData.h for writing, $!";
print TILEDATA_H << "EOF"; $text = << "EOF";
#ifndef _GUARD_PROJECTBuGS_FILEtileData_ #ifndef _GUARD_PROJECTBuGS_FILEtileData_
#define _GUARD_PROJECTBuGS_FILEtileData_ #define _GUARD_PROJECTBuGS_FILEtileData_
EOF EOF
print $fh $text;
foreach my $equate (sort keys %gEquates) foreach my $equate (sort keys %gEquates)
{ {
print TILEDATA_H "#define $equate " . $gEquates{$equate} . "\n"; print $fh "#define $equate " . $gEquates{$equate} . "\n";
} }
print TILEDATA_H << "EOF"; $text = << "EOF";
#endif /* define _GUARD_PROJECTBuGS_FILEtileData_ */ #endif /* define _GUARD_PROJECTBuGS_FILEtileData_ */
EOF EOF
print $fh $text;
close(TILEDATA_H); close($fh);