diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml index 942e3e8..6c4e357 100644 --- a/.idea/dictionaries/project.xml +++ b/.idea/dictionaries/project.xml @@ -7,6 +7,7 @@ addsp dechl inchl + instrs jpcc jphl jrcc diff --git a/boot/agb.bin b/boot/agb.bin new file mode 100644 index 0000000..4d38be5 Binary files /dev/null and b/boot/agb.bin differ diff --git a/boot/agb.sym b/boot/agb.sym new file mode 100644 index 0000000..cc4e5ca --- /dev/null +++ b/boot/agb.sym @@ -0,0 +1,176 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0008 ClearLogoGDMA +BOOT:000d ClearLogoGDMA.end +BOOT:000d ClearLogoTilesGDMA +BOOT:0012 OverrideColors +BOOT:0042 LogoTopHalf +BOOT:005a LogoBottomHalf +BOOT:0072 RTile +BOOT:007a RTile.end +BOOT:007a LogoTilemapChecksums +BOOT:007c LogoTilemapChecksums.end +BOOT:007c Setup +BOOT:0093 Setup.clearOAM +BOOT:009e Setup.processLogo +BOOT:00b2 Setup.copyRTile +BOOT:00d8 Setup.checkLogo +BOOT:00db Setup.logoFailure +BOOT:00e7 Setup.computeChecksum +BOOT:00ed Setup.checksumFailure +BOOT:00f5 Setup.done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +BOOT:0200 ClearVRAM +BOOT:0203 ClearUntilMemBoundary +BOOT:0204 ClearUntilMemBoundary.loop +BOOT:020a Memcpy +BOOT:0211 WaitVBlank +BOOT:0217 WaitVBlank.wait +BOOT:021d PollJoypad +BOOT:024a SetOBJAndBGPals +BOOT:0252 SetOBJAndBGPals.writeOBJPalData +BOOT:025c SetOBJAndBGPals.writeBGPalData +BOOT:0262 CommitBGPalettes +BOOT:0275 SetupSound +BOOT:028b SetupSound.initWaveRAM +BOOT:0291 DoLogoAnimation +BOOT:02a5 DoLogoAnimation.writeNintendoLogoMap +BOOT:02b0 DoLogoAnimation.dontWriteNintendoLogo +BOOT:02d3 DoLogoAnimation.changePaletteRow +BOOT:02d5 DoLogoAnimation.changePaletteBlock +BOOT:02d7 DoLogoAnimation.changePaletteLoop +BOOT:02f1 DoLogoAnimation.dontWriteLogoAttrMap +BOOT:02ff DoLogoAnimation.playSFX +BOOT:0306 DoLogoAnimation.dontAnimateLogo +BOOT:0306 DoLogoAnimation.dontPlaySFX +BOOT:0317 DoLogoAnimation.stepAnimation +BOOT:031c PerformFadeout +BOOT:031e PerformFadeout.loop +BOOT:033e PerformFadeout.clearLogoArea +BOOT:0341 PerformFadeout.clearLogoTiles +BOOT:034a PerformFadeout.fadePalettes +BOOT:0352 PerformFadeout.fadeColor +BOOT:035a PerformFadeout.redCap +BOOT:036e PerformFadeout.greenCap +BOOT:0384 PerformFadeout.blueCap +BOOT:038f DecodeLogoHalf +BOOT:0391 DecodeLogoHalf.decodeTileQuarter +BOOT:039a DecodeLogoHalf.decodingLeftHalf +BOOT:03a8 DecodeLogoHalf.decodingRightHalf +BOOT:03bd DecodeLogoHalf.goToRightHalf +BOOT:03bf DecodeLogoHalf.decodingTopHalf +BOOT:03c6 DecompressFirstNibble +BOOT:03c7 DecompressSecondNibble +BOOT:03ca DecompressSecondNibble.decompressBit +BOOT:03da WriteLogoTilemap +BOOT:03e2 WriteLogoTilemap.writeRow +BOOT:03e4 WriteLogoTilemap.writeByte +BOOT:03ef WriteLogoTilemap.done +BOOT:03f0 SetupGameBoyLogo +BOOT:03ff SetupGameBoyLogo.copyLogoRow +BOOT:041e SetupGameBoyLogo.copyRTile +BOOT:042c SetupGameBoyLogo.writeAttrRow +BOOT:042e SetupGameBoyLogo.writeAttrByte +BOOT:0441 SetupGameBoyLogo.writeTilemapByte +BOOT:0449 SetupGameBoyLogo.notFirstRow +BOOT:0450 SetupGameBoyLogo.notSecondRow +BOOT:045c SetupGameBoyLogo.initBGPalsLoop +BOOT:0488 SetupGameBoyLogo.usingOldLicensee +BOOT:048c SetupGameBoyLogo.checkMadeByNintendo +BOOT:0495 SetupGameBoyLogo.checksumTitle +BOOT:04a3 SetupGameBoyLogo.seekTitleChecksum +BOOT:04af SetupGameBoyLogo.foundTitleChecksum +BOOT:04bb SetupGameBoyLogo.seekFourthLetter +BOOT:04ce SetupGameBoyLogo.useDefaultIndex +BOOT:04d0 SetupGameBoyLogo.gotIndex +BOOT:04e9 WriteShuffledPalTriplets +BOOT:04f5 WriteShuffledPalTriplets.get3Indexes +BOOT:04fb WriteShuffledPalTriplets.bit0Set +BOOT:0501 WriteShuffledPalTriplets.cancelBit0Set +BOOT:0507 WriteShuffledPalTriplets.bit1Set +BOOT:050f WriteShuffledPalTriplets.cancelBit1Set +BOOT:0518 WriteShuffledPalTriplets.bit2Reset +BOOT:0528 ApplyPaletteOverride +BOOT:0539 ApplyPaletteOverride.copyPalette +BOOT:0564 GetPalettes +BOOT:0566 GetPalettes.copyPalette +BOOT:057b AddPalTripletOffset +BOOT:0582 AddPalTripletOffset.loop +BOOT:0588 AddPalTripletOffset.done +BOOT:0589 PickDMGPalette +BOOT:0596 PickDMGPalette.seekButtonCombo +BOOT:05a0 PickDMGPalette.jumpToDone +BOOT:05a2 PickDMGPalette.buttonComboFound +BOOT:05cf PickDMGPalette.done +BOOT:05d0 SetupCompatibility +BOOT:05de SetupCompatibility.dmgMode +BOOT:05fe SetupCompatibility.tryWriteLogoTilemap +BOOT:0606 SetupCompatibility.done +BOOT:0607 GameBoyLogoTiles +BOOT:06c7 GameBoyLogoTiles.end +BOOT:06c7 TitleChecksums +BOOT:0708 TitleChecksums.ambiguous +BOOT:0716 TitleChecksums.end +BOOT:0716 TitleFourthLetters +BOOT:0724 TitleFourthLetters.row +BOOT:0733 TitleFourthLetters.end +BOOT:0733 PalTripletIDsAndFlags +BOOT:0791 PaletteOffsets +BOOT:07e8 Palettes +BOOT:08d8 BootAnimationColors +BOOT:08e4 BootAnimationColors.end +BOOT:08e4 JoypadCombos +BOOT:08f0 JoypadCombos.end +BOOT:08f0 JoypadCombosTripletIDsAndFlags +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vTileMap +00:98c2 vGameBoyLogoMap +00:9904 vBigNintendoLogoMap +00:99a7 vNintendoLogoMap +01:8000 vTiles +01:8080 vGameBoyLogoTiles +01:8380 vNintendoLogoTiles +01:83e0 vSecondRTile +01:83f0 vNintendoLogoTilesEnd +01:9800 vAttrMap +01:98c2 vGameBoyLogoAttrs +01:9904 vBigNintendoLogoAttrs +01:99a7 vNintendoLogoAttrs +02:d000 wWorkRAM +02:d000 wTitleChecksum +02:d002 wPreventTerminationCounter +02:d003 wHeldButtons +02:d004 wPressedButtons +02:d005 wPaletteOverrideIndex +02:d006 wWhichPalTripletCopy +02:d007 wOldWhichPalTriplet +02:d008 wWhichPalTriplet +02:d009 wPalShufflingFlagsCopy +02:d00a wOldPalShufflingFlags +02:d00b wPalShufflingFlags +02:d300 wZeroBuffer +02:d800 wOBJPalBuffer +02:d840 wOBJPalBuffer.end +02:d840 wBGPalBuffer +02:d880 wBGPalBuffer.end +02:d900 wPalOfsBuffer +02:d95a wPalOfsBuffer.end +02:d960 wPalOfsBuffer.realEnd +02:da00 wPalBuffer +00:ff80 hLogoBuffer +00:fffe hStackBottom diff --git a/boot/agb0.bin b/boot/agb0.bin new file mode 100644 index 0000000..e1bfe5d Binary files /dev/null and b/boot/agb0.bin differ diff --git a/boot/agb0.sym b/boot/agb0.sym new file mode 100644 index 0000000..cc4e5ca --- /dev/null +++ b/boot/agb0.sym @@ -0,0 +1,176 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0008 ClearLogoGDMA +BOOT:000d ClearLogoGDMA.end +BOOT:000d ClearLogoTilesGDMA +BOOT:0012 OverrideColors +BOOT:0042 LogoTopHalf +BOOT:005a LogoBottomHalf +BOOT:0072 RTile +BOOT:007a RTile.end +BOOT:007a LogoTilemapChecksums +BOOT:007c LogoTilemapChecksums.end +BOOT:007c Setup +BOOT:0093 Setup.clearOAM +BOOT:009e Setup.processLogo +BOOT:00b2 Setup.copyRTile +BOOT:00d8 Setup.checkLogo +BOOT:00db Setup.logoFailure +BOOT:00e7 Setup.computeChecksum +BOOT:00ed Setup.checksumFailure +BOOT:00f5 Setup.done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +BOOT:0200 ClearVRAM +BOOT:0203 ClearUntilMemBoundary +BOOT:0204 ClearUntilMemBoundary.loop +BOOT:020a Memcpy +BOOT:0211 WaitVBlank +BOOT:0217 WaitVBlank.wait +BOOT:021d PollJoypad +BOOT:024a SetOBJAndBGPals +BOOT:0252 SetOBJAndBGPals.writeOBJPalData +BOOT:025c SetOBJAndBGPals.writeBGPalData +BOOT:0262 CommitBGPalettes +BOOT:0275 SetupSound +BOOT:028b SetupSound.initWaveRAM +BOOT:0291 DoLogoAnimation +BOOT:02a5 DoLogoAnimation.writeNintendoLogoMap +BOOT:02b0 DoLogoAnimation.dontWriteNintendoLogo +BOOT:02d3 DoLogoAnimation.changePaletteRow +BOOT:02d5 DoLogoAnimation.changePaletteBlock +BOOT:02d7 DoLogoAnimation.changePaletteLoop +BOOT:02f1 DoLogoAnimation.dontWriteLogoAttrMap +BOOT:02ff DoLogoAnimation.playSFX +BOOT:0306 DoLogoAnimation.dontAnimateLogo +BOOT:0306 DoLogoAnimation.dontPlaySFX +BOOT:0317 DoLogoAnimation.stepAnimation +BOOT:031c PerformFadeout +BOOT:031e PerformFadeout.loop +BOOT:033e PerformFadeout.clearLogoArea +BOOT:0341 PerformFadeout.clearLogoTiles +BOOT:034a PerformFadeout.fadePalettes +BOOT:0352 PerformFadeout.fadeColor +BOOT:035a PerformFadeout.redCap +BOOT:036e PerformFadeout.greenCap +BOOT:0384 PerformFadeout.blueCap +BOOT:038f DecodeLogoHalf +BOOT:0391 DecodeLogoHalf.decodeTileQuarter +BOOT:039a DecodeLogoHalf.decodingLeftHalf +BOOT:03a8 DecodeLogoHalf.decodingRightHalf +BOOT:03bd DecodeLogoHalf.goToRightHalf +BOOT:03bf DecodeLogoHalf.decodingTopHalf +BOOT:03c6 DecompressFirstNibble +BOOT:03c7 DecompressSecondNibble +BOOT:03ca DecompressSecondNibble.decompressBit +BOOT:03da WriteLogoTilemap +BOOT:03e2 WriteLogoTilemap.writeRow +BOOT:03e4 WriteLogoTilemap.writeByte +BOOT:03ef WriteLogoTilemap.done +BOOT:03f0 SetupGameBoyLogo +BOOT:03ff SetupGameBoyLogo.copyLogoRow +BOOT:041e SetupGameBoyLogo.copyRTile +BOOT:042c SetupGameBoyLogo.writeAttrRow +BOOT:042e SetupGameBoyLogo.writeAttrByte +BOOT:0441 SetupGameBoyLogo.writeTilemapByte +BOOT:0449 SetupGameBoyLogo.notFirstRow +BOOT:0450 SetupGameBoyLogo.notSecondRow +BOOT:045c SetupGameBoyLogo.initBGPalsLoop +BOOT:0488 SetupGameBoyLogo.usingOldLicensee +BOOT:048c SetupGameBoyLogo.checkMadeByNintendo +BOOT:0495 SetupGameBoyLogo.checksumTitle +BOOT:04a3 SetupGameBoyLogo.seekTitleChecksum +BOOT:04af SetupGameBoyLogo.foundTitleChecksum +BOOT:04bb SetupGameBoyLogo.seekFourthLetter +BOOT:04ce SetupGameBoyLogo.useDefaultIndex +BOOT:04d0 SetupGameBoyLogo.gotIndex +BOOT:04e9 WriteShuffledPalTriplets +BOOT:04f5 WriteShuffledPalTriplets.get3Indexes +BOOT:04fb WriteShuffledPalTriplets.bit0Set +BOOT:0501 WriteShuffledPalTriplets.cancelBit0Set +BOOT:0507 WriteShuffledPalTriplets.bit1Set +BOOT:050f WriteShuffledPalTriplets.cancelBit1Set +BOOT:0518 WriteShuffledPalTriplets.bit2Reset +BOOT:0528 ApplyPaletteOverride +BOOT:0539 ApplyPaletteOverride.copyPalette +BOOT:0564 GetPalettes +BOOT:0566 GetPalettes.copyPalette +BOOT:057b AddPalTripletOffset +BOOT:0582 AddPalTripletOffset.loop +BOOT:0588 AddPalTripletOffset.done +BOOT:0589 PickDMGPalette +BOOT:0596 PickDMGPalette.seekButtonCombo +BOOT:05a0 PickDMGPalette.jumpToDone +BOOT:05a2 PickDMGPalette.buttonComboFound +BOOT:05cf PickDMGPalette.done +BOOT:05d0 SetupCompatibility +BOOT:05de SetupCompatibility.dmgMode +BOOT:05fe SetupCompatibility.tryWriteLogoTilemap +BOOT:0606 SetupCompatibility.done +BOOT:0607 GameBoyLogoTiles +BOOT:06c7 GameBoyLogoTiles.end +BOOT:06c7 TitleChecksums +BOOT:0708 TitleChecksums.ambiguous +BOOT:0716 TitleChecksums.end +BOOT:0716 TitleFourthLetters +BOOT:0724 TitleFourthLetters.row +BOOT:0733 TitleFourthLetters.end +BOOT:0733 PalTripletIDsAndFlags +BOOT:0791 PaletteOffsets +BOOT:07e8 Palettes +BOOT:08d8 BootAnimationColors +BOOT:08e4 BootAnimationColors.end +BOOT:08e4 JoypadCombos +BOOT:08f0 JoypadCombos.end +BOOT:08f0 JoypadCombosTripletIDsAndFlags +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vTileMap +00:98c2 vGameBoyLogoMap +00:9904 vBigNintendoLogoMap +00:99a7 vNintendoLogoMap +01:8000 vTiles +01:8080 vGameBoyLogoTiles +01:8380 vNintendoLogoTiles +01:83e0 vSecondRTile +01:83f0 vNintendoLogoTilesEnd +01:9800 vAttrMap +01:98c2 vGameBoyLogoAttrs +01:9904 vBigNintendoLogoAttrs +01:99a7 vNintendoLogoAttrs +02:d000 wWorkRAM +02:d000 wTitleChecksum +02:d002 wPreventTerminationCounter +02:d003 wHeldButtons +02:d004 wPressedButtons +02:d005 wPaletteOverrideIndex +02:d006 wWhichPalTripletCopy +02:d007 wOldWhichPalTriplet +02:d008 wWhichPalTriplet +02:d009 wPalShufflingFlagsCopy +02:d00a wOldPalShufflingFlags +02:d00b wPalShufflingFlags +02:d300 wZeroBuffer +02:d800 wOBJPalBuffer +02:d840 wOBJPalBuffer.end +02:d840 wBGPalBuffer +02:d880 wBGPalBuffer.end +02:d900 wPalOfsBuffer +02:d95a wPalOfsBuffer.end +02:d960 wPalOfsBuffer.realEnd +02:da00 wPalBuffer +00:ff80 hLogoBuffer +00:fffe hStackBottom diff --git a/boot/cgb.bin b/boot/cgb.bin new file mode 100644 index 0000000..7368ee9 Binary files /dev/null and b/boot/cgb.bin differ diff --git a/boot/cgb.sym b/boot/cgb.sym new file mode 100644 index 0000000..46c0809 --- /dev/null +++ b/boot/cgb.sym @@ -0,0 +1,176 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0008 ClearLogoGDMA +BOOT:000d ClearLogoGDMA.end +BOOT:000d ClearLogoTilesGDMA +BOOT:0012 OverrideColors +BOOT:0042 LogoTopHalf +BOOT:005a LogoBottomHalf +BOOT:0072 RTile +BOOT:007a RTile.end +BOOT:007a LogoTilemapChecksums +BOOT:007c LogoTilemapChecksums.end +BOOT:007c Setup +BOOT:0093 Setup.clearOAM +BOOT:009e Setup.processLogo +BOOT:00b2 Setup.copyRTile +BOOT:00d8 Setup.checkLogo +BOOT:00db Setup.logoFailure +BOOT:00e7 Setup.computeChecksum +BOOT:00ed Setup.checksumFailure +BOOT:00f6 Setup.done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +BOOT:0200 ClearVRAM +BOOT:0203 ClearUntilMemBoundary +BOOT:0204 ClearUntilMemBoundary.loop +BOOT:020a Memcpy +BOOT:0211 WaitVBlank +BOOT:0217 WaitVBlank.wait +BOOT:021d PollJoypad +BOOT:024a SetOBJAndBGPals +BOOT:0252 SetOBJAndBGPals.writeOBJPalData +BOOT:025c SetOBJAndBGPals.writeBGPalData +BOOT:0262 CommitBGPalettes +BOOT:0275 SetupSound +BOOT:028b SetupSound.initWaveRAM +BOOT:0291 DoLogoAnimation +BOOT:02a5 DoLogoAnimation.writeNintendoLogoMap +BOOT:02b0 DoLogoAnimation.dontWriteNintendoLogo +BOOT:02d3 DoLogoAnimation.changePaletteRow +BOOT:02d5 DoLogoAnimation.changePaletteBlock +BOOT:02d7 DoLogoAnimation.changePaletteLoop +BOOT:02f1 DoLogoAnimation.dontWriteLogoAttrMap +BOOT:02ff DoLogoAnimation.playSFX +BOOT:0306 DoLogoAnimation.dontAnimateLogo +BOOT:0306 DoLogoAnimation.dontPlaySFX +BOOT:0317 DoLogoAnimation.stepAnimation +BOOT:031c PerformFadeout +BOOT:031e PerformFadeout.loop +BOOT:033e PerformFadeout.clearLogoArea +BOOT:0341 PerformFadeout.clearLogoTiles +BOOT:034a PerformFadeout.fadePalettes +BOOT:0352 PerformFadeout.fadeColor +BOOT:035a PerformFadeout.redCap +BOOT:036e PerformFadeout.greenCap +BOOT:0384 PerformFadeout.blueCap +BOOT:038f DecodeLogoHalf +BOOT:0391 DecodeLogoHalf.decodeTileQuarter +BOOT:039a DecodeLogoHalf.decodingLeftHalf +BOOT:03a8 DecodeLogoHalf.decodingRightHalf +BOOT:03bd DecodeLogoHalf.goToRightHalf +BOOT:03bf DecodeLogoHalf.decodingTopHalf +BOOT:03c6 DecompressFirstNibble +BOOT:03c7 DecompressSecondNibble +BOOT:03ca DecompressSecondNibble.decompressBit +BOOT:03da WriteLogoTilemap +BOOT:03e2 WriteLogoTilemap.writeRow +BOOT:03e4 WriteLogoTilemap.writeByte +BOOT:03ef WriteLogoTilemap.done +BOOT:03f0 SetupGameBoyLogo +BOOT:03ff SetupGameBoyLogo.copyLogoRow +BOOT:041e SetupGameBoyLogo.copyRTile +BOOT:042c SetupGameBoyLogo.writeAttrRow +BOOT:042e SetupGameBoyLogo.writeAttrByte +BOOT:0441 SetupGameBoyLogo.writeTilemapByte +BOOT:0449 SetupGameBoyLogo.notFirstRow +BOOT:0450 SetupGameBoyLogo.notSecondRow +BOOT:045c SetupGameBoyLogo.initBGPalsLoop +BOOT:0488 SetupGameBoyLogo.usingOldLicensee +BOOT:048c SetupGameBoyLogo.checkMadeByNintendo +BOOT:0495 SetupGameBoyLogo.checksumTitle +BOOT:04a3 SetupGameBoyLogo.seekTitleChecksum +BOOT:04af SetupGameBoyLogo.foundTitleChecksum +BOOT:04bb SetupGameBoyLogo.seekFourthLetter +BOOT:04ce SetupGameBoyLogo.useDefaultIndex +BOOT:04d0 SetupGameBoyLogo.gotIndex +BOOT:04e9 WriteShuffledPalTriplets +BOOT:04f5 WriteShuffledPalTriplets.get3Indexes +BOOT:04fb WriteShuffledPalTriplets.bit0Set +BOOT:0501 WriteShuffledPalTriplets.cancelBit0Set +BOOT:0507 WriteShuffledPalTriplets.bit1Set +BOOT:050f WriteShuffledPalTriplets.cancelBit1Set +BOOT:0518 WriteShuffledPalTriplets.bit2Reset +BOOT:0528 ApplyPaletteOverride +BOOT:0539 ApplyPaletteOverride.copyPalette +BOOT:0564 GetPalettes +BOOT:0566 GetPalettes.copyPalette +BOOT:057b AddPalTripletOffset +BOOT:0582 AddPalTripletOffset.loop +BOOT:0588 AddPalTripletOffset.done +BOOT:0589 PickDMGPalette +BOOT:0596 PickDMGPalette.seekButtonCombo +BOOT:05a0 PickDMGPalette.jumpToDone +BOOT:05a2 PickDMGPalette.buttonComboFound +BOOT:05cf PickDMGPalette.done +BOOT:05d0 SetupCompatibility +BOOT:05de SetupCompatibility.dmgMode +BOOT:05fe SetupCompatibility.tryWriteLogoTilemap +BOOT:0606 SetupCompatibility.done +BOOT:0607 GameBoyLogoTiles +BOOT:06c7 GameBoyLogoTiles.end +BOOT:06c7 TitleChecksums +BOOT:0708 TitleChecksums.ambiguous +BOOT:0716 TitleChecksums.end +BOOT:0716 TitleFourthLetters +BOOT:0724 TitleFourthLetters.row +BOOT:0733 TitleFourthLetters.end +BOOT:0733 PalTripletIDsAndFlags +BOOT:0791 PaletteOffsets +BOOT:07e8 Palettes +BOOT:08d8 BootAnimationColors +BOOT:08e4 BootAnimationColors.end +BOOT:08e4 JoypadCombos +BOOT:08f0 JoypadCombos.end +BOOT:08f0 JoypadCombosTripletIDsAndFlags +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vTileMap +00:98c2 vGameBoyLogoMap +00:9904 vBigNintendoLogoMap +00:99a7 vNintendoLogoMap +01:8000 vTiles +01:8080 vGameBoyLogoTiles +01:8380 vNintendoLogoTiles +01:83e0 vSecondRTile +01:83f0 vNintendoLogoTilesEnd +01:9800 vAttrMap +01:98c2 vGameBoyLogoAttrs +01:9904 vBigNintendoLogoAttrs +01:99a7 vNintendoLogoAttrs +02:d000 wWorkRAM +02:d000 wTitleChecksum +02:d002 wPreventTerminationCounter +02:d003 wHeldButtons +02:d004 wPressedButtons +02:d005 wPaletteOverrideIndex +02:d006 wWhichPalTripletCopy +02:d007 wOldWhichPalTriplet +02:d008 wWhichPalTriplet +02:d009 wPalShufflingFlagsCopy +02:d00a wOldPalShufflingFlags +02:d00b wPalShufflingFlags +02:d300 wZeroBuffer +02:d800 wOBJPalBuffer +02:d840 wOBJPalBuffer.end +02:d840 wBGPalBuffer +02:d880 wBGPalBuffer.end +02:d900 wPalOfsBuffer +02:d95a wPalOfsBuffer.end +02:d960 wPalOfsBuffer.realEnd +02:da00 wPalBuffer +00:ff80 hLogoBuffer +00:fffe hStackBottom diff --git a/boot/cgb0.bin b/boot/cgb0.bin new file mode 100644 index 0000000..c72d4f9 Binary files /dev/null and b/boot/cgb0.bin differ diff --git a/boot/cgb0.sym b/boot/cgb0.sym new file mode 100644 index 0000000..b0463db --- /dev/null +++ b/boot/cgb0.sym @@ -0,0 +1,176 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0008 ClearLogoGDMA +BOOT:000d ClearLogoGDMA.end +BOOT:000d ClearLogoTilesGDMA +BOOT:0012 OverrideColors +BOOT:0042 LogoTopHalf +BOOT:005a LogoBottomHalf +BOOT:0072 RTile +BOOT:007a RTile.end +BOOT:007a LogoTilemapChecksums +BOOT:007c LogoTilemapChecksums.end +BOOT:007c Setup +BOOT:0093 Setup.clearOAM +BOOT:009e Setup.processLogo +BOOT:00b2 Setup.copyRTile +BOOT:00d8 Setup.checkLogo +BOOT:00db Setup.logoFailure +BOOT:00e7 Setup.computeChecksum +BOOT:00ed Setup.checksumFailure +BOOT:00f6 Setup.done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +BOOT:0200 ClearVRAM +BOOT:0203 ClearUntilMemBoundary +BOOT:0204 ClearUntilMemBoundary.loop +BOOT:020a Memcpy +BOOT:0211 WaitVBlank +BOOT:0217 WaitVBlank.wait +BOOT:021d PollJoypad +BOOT:024a SetOBJAndBGPals +BOOT:0252 SetOBJAndBGPals.writeOBJPalData +BOOT:025c SetOBJAndBGPals.writeBGPalData +BOOT:0262 CommitBGPalettes +BOOT:0275 SetupSound +BOOT:0286 DoLogoAnimation +BOOT:029a DoLogoAnimation.writeNintendoLogoMap +BOOT:02a5 DoLogoAnimation.dontWriteNintendoLogo +BOOT:02c8 DoLogoAnimation.changePaletteRow +BOOT:02ca DoLogoAnimation.changePaletteBlock +BOOT:02cc DoLogoAnimation.changePaletteLoop +BOOT:02e6 DoLogoAnimation.dontWriteLogoAttrMap +BOOT:02f4 DoLogoAnimation.playSFX +BOOT:02fb DoLogoAnimation.dontAnimateLogo +BOOT:02fb DoLogoAnimation.dontPlaySFX +BOOT:030c DoLogoAnimation.stepAnimation +BOOT:0311 PerformFadeout +BOOT:0313 PerformFadeout.loop +BOOT:0333 PerformFadeout.clearLogoArea +BOOT:0336 PerformFadeout.clearLogoTiles +BOOT:033f PerformFadeout.fadePalettes +BOOT:0347 PerformFadeout.fadeColor +BOOT:034f PerformFadeout.redCap +BOOT:0363 PerformFadeout.greenCap +BOOT:0379 PerformFadeout.blueCap +BOOT:0384 DecodeLogoHalf +BOOT:0386 DecodeLogoHalf.decodeTileQuarter +BOOT:038f DecodeLogoHalf.decodingLeftHalf +BOOT:039d DecodeLogoHalf.decodingRightHalf +BOOT:03b2 DecodeLogoHalf.goToRightHalf +BOOT:03b4 DecodeLogoHalf.decodingTopHalf +BOOT:03bb DecompressFirstNibble +BOOT:03bc DecompressSecondNibble +BOOT:03bf DecompressSecondNibble.decompressBit +BOOT:03cf WriteLogoTilemap +BOOT:03d7 WriteLogoTilemap.writeRow +BOOT:03d9 WriteLogoTilemap.writeByte +BOOT:03e4 WriteLogoTilemap.done +BOOT:03e5 SetupGameBoyLogo +BOOT:03f4 SetupGameBoyLogo.copyLogoTile +BOOT:03f6 SetupGameBoyLogo.copyLogoRow +BOOT:0418 SetupGameBoyLogo.copyRTile +BOOT:0426 SetupGameBoyLogo.writeAttrRow +BOOT:0428 SetupGameBoyLogo.writeAttrByte +BOOT:043b SetupGameBoyLogo.writeTilemapByte +BOOT:0443 SetupGameBoyLogo.notFirstRow +BOOT:044a SetupGameBoyLogo.notSecondRow +BOOT:0456 SetupGameBoyLogo.initBGPalsLoop +BOOT:0482 SetupGameBoyLogo.usingOldLicensee +BOOT:0486 SetupGameBoyLogo.checkMadeByNintendo +BOOT:048f SetupGameBoyLogo.checksumTitle +BOOT:049d SetupGameBoyLogo.seekTitleChecksum +BOOT:04a9 SetupGameBoyLogo.foundTitleChecksum +BOOT:04b5 SetupGameBoyLogo.seekFourthLetter +BOOT:04c8 SetupGameBoyLogo.useDefaultIndex +BOOT:04ca SetupGameBoyLogo.gotIndex +BOOT:04e9 WriteShuffledPalTriplets +BOOT:04f5 WriteShuffledPalTriplets.get3Indexes +BOOT:04fb WriteShuffledPalTriplets.bit0Set +BOOT:0501 WriteShuffledPalTriplets.cancelBit0Set +BOOT:0507 WriteShuffledPalTriplets.bit1Set +BOOT:050f WriteShuffledPalTriplets.cancelBit1Set +BOOT:0518 WriteShuffledPalTriplets.bit2Reset +BOOT:0528 ApplyPaletteOverride +BOOT:0539 ApplyPaletteOverride.copyPalette +BOOT:0564 GetPalettes +BOOT:0566 GetPalettes.copyPalette +BOOT:057b AddPalTripletOffset +BOOT:0582 AddPalTripletOffset.loop +BOOT:0588 AddPalTripletOffset.done +BOOT:0589 PickDMGPalette +BOOT:0596 PickDMGPalette.seekButtonCombo +BOOT:05a0 PickDMGPalette.jumpToDone +BOOT:05a2 PickDMGPalette.buttonComboFound +BOOT:05cf PickDMGPalette.done +BOOT:05d0 SetupCompatibility +BOOT:05de SetupCompatibility.dmgMode +BOOT:05fe SetupCompatibility.tryWriteLogoTilemap +BOOT:0606 SetupCompatibility.done +BOOT:0607 GameBoyLogoTiles +BOOT:06c7 GameBoyLogoTiles.end +BOOT:06c7 TitleChecksums +BOOT:0708 TitleChecksums.ambiguous +BOOT:0716 TitleChecksums.end +BOOT:0716 TitleFourthLetters +BOOT:0724 TitleFourthLetters.row +BOOT:0733 TitleFourthLetters.end +BOOT:0733 PalTripletIDsAndFlags +BOOT:0791 PaletteOffsets +BOOT:07e8 Palettes +BOOT:08d8 BootAnimationColors +BOOT:08e4 BootAnimationColors.end +BOOT:08e4 JoypadCombos +BOOT:08f0 JoypadCombos.end +BOOT:08f0 JoypadCombosTripletIDsAndFlags +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vTileMap +00:98c2 vGameBoyLogoMap +00:9904 vBigNintendoLogoMap +00:99a7 vNintendoLogoMap +01:8000 vTiles +01:8080 vGameBoyLogoTiles +01:8380 vNintendoLogoTiles +01:83e0 vSecondRTile +01:83f0 vNintendoLogoTilesEnd +01:9800 vAttrMap +01:98c2 vGameBoyLogoAttrs +01:9904 vBigNintendoLogoAttrs +01:99a7 vNintendoLogoAttrs +02:d000 wWorkRAM +02:d000 wTitleChecksum +02:d002 wPreventTerminationCounter +02:d003 wHeldButtons +02:d004 wPressedButtons +02:d005 wPaletteOverrideIndex +02:d006 wWhichPalTripletCopy +02:d007 wOldWhichPalTriplet +02:d008 wWhichPalTriplet +02:d009 wPalShufflingFlagsCopy +02:d00a wOldPalShufflingFlags +02:d00b wPalShufflingFlags +02:d300 wZeroBuffer +02:d800 wOBJPalBuffer +02:d840 wOBJPalBuffer.end +02:d840 wBGPalBuffer +02:d880 wBGPalBuffer.end +02:d900 wPalOfsBuffer +02:d95a wPalOfsBuffer.end +02:d960 wPalOfsBuffer.realEnd +02:da00 wPalBuffer +00:ff80 hLogoBuffer +00:fffe hStackBottom diff --git a/boot/cgbE.bin b/boot/cgbE.bin new file mode 100644 index 0000000..3a66fac Binary files /dev/null and b/boot/cgbE.bin differ diff --git a/boot/cgbE.sym b/boot/cgbE.sym new file mode 100644 index 0000000..46c0809 --- /dev/null +++ b/boot/cgbE.sym @@ -0,0 +1,176 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0008 ClearLogoGDMA +BOOT:000d ClearLogoGDMA.end +BOOT:000d ClearLogoTilesGDMA +BOOT:0012 OverrideColors +BOOT:0042 LogoTopHalf +BOOT:005a LogoBottomHalf +BOOT:0072 RTile +BOOT:007a RTile.end +BOOT:007a LogoTilemapChecksums +BOOT:007c LogoTilemapChecksums.end +BOOT:007c Setup +BOOT:0093 Setup.clearOAM +BOOT:009e Setup.processLogo +BOOT:00b2 Setup.copyRTile +BOOT:00d8 Setup.checkLogo +BOOT:00db Setup.logoFailure +BOOT:00e7 Setup.computeChecksum +BOOT:00ed Setup.checksumFailure +BOOT:00f6 Setup.done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +BOOT:0200 ClearVRAM +BOOT:0203 ClearUntilMemBoundary +BOOT:0204 ClearUntilMemBoundary.loop +BOOT:020a Memcpy +BOOT:0211 WaitVBlank +BOOT:0217 WaitVBlank.wait +BOOT:021d PollJoypad +BOOT:024a SetOBJAndBGPals +BOOT:0252 SetOBJAndBGPals.writeOBJPalData +BOOT:025c SetOBJAndBGPals.writeBGPalData +BOOT:0262 CommitBGPalettes +BOOT:0275 SetupSound +BOOT:028b SetupSound.initWaveRAM +BOOT:0291 DoLogoAnimation +BOOT:02a5 DoLogoAnimation.writeNintendoLogoMap +BOOT:02b0 DoLogoAnimation.dontWriteNintendoLogo +BOOT:02d3 DoLogoAnimation.changePaletteRow +BOOT:02d5 DoLogoAnimation.changePaletteBlock +BOOT:02d7 DoLogoAnimation.changePaletteLoop +BOOT:02f1 DoLogoAnimation.dontWriteLogoAttrMap +BOOT:02ff DoLogoAnimation.playSFX +BOOT:0306 DoLogoAnimation.dontAnimateLogo +BOOT:0306 DoLogoAnimation.dontPlaySFX +BOOT:0317 DoLogoAnimation.stepAnimation +BOOT:031c PerformFadeout +BOOT:031e PerformFadeout.loop +BOOT:033e PerformFadeout.clearLogoArea +BOOT:0341 PerformFadeout.clearLogoTiles +BOOT:034a PerformFadeout.fadePalettes +BOOT:0352 PerformFadeout.fadeColor +BOOT:035a PerformFadeout.redCap +BOOT:036e PerformFadeout.greenCap +BOOT:0384 PerformFadeout.blueCap +BOOT:038f DecodeLogoHalf +BOOT:0391 DecodeLogoHalf.decodeTileQuarter +BOOT:039a DecodeLogoHalf.decodingLeftHalf +BOOT:03a8 DecodeLogoHalf.decodingRightHalf +BOOT:03bd DecodeLogoHalf.goToRightHalf +BOOT:03bf DecodeLogoHalf.decodingTopHalf +BOOT:03c6 DecompressFirstNibble +BOOT:03c7 DecompressSecondNibble +BOOT:03ca DecompressSecondNibble.decompressBit +BOOT:03da WriteLogoTilemap +BOOT:03e2 WriteLogoTilemap.writeRow +BOOT:03e4 WriteLogoTilemap.writeByte +BOOT:03ef WriteLogoTilemap.done +BOOT:03f0 SetupGameBoyLogo +BOOT:03ff SetupGameBoyLogo.copyLogoRow +BOOT:041e SetupGameBoyLogo.copyRTile +BOOT:042c SetupGameBoyLogo.writeAttrRow +BOOT:042e SetupGameBoyLogo.writeAttrByte +BOOT:0441 SetupGameBoyLogo.writeTilemapByte +BOOT:0449 SetupGameBoyLogo.notFirstRow +BOOT:0450 SetupGameBoyLogo.notSecondRow +BOOT:045c SetupGameBoyLogo.initBGPalsLoop +BOOT:0488 SetupGameBoyLogo.usingOldLicensee +BOOT:048c SetupGameBoyLogo.checkMadeByNintendo +BOOT:0495 SetupGameBoyLogo.checksumTitle +BOOT:04a3 SetupGameBoyLogo.seekTitleChecksum +BOOT:04af SetupGameBoyLogo.foundTitleChecksum +BOOT:04bb SetupGameBoyLogo.seekFourthLetter +BOOT:04ce SetupGameBoyLogo.useDefaultIndex +BOOT:04d0 SetupGameBoyLogo.gotIndex +BOOT:04e9 WriteShuffledPalTriplets +BOOT:04f5 WriteShuffledPalTriplets.get3Indexes +BOOT:04fb WriteShuffledPalTriplets.bit0Set +BOOT:0501 WriteShuffledPalTriplets.cancelBit0Set +BOOT:0507 WriteShuffledPalTriplets.bit1Set +BOOT:050f WriteShuffledPalTriplets.cancelBit1Set +BOOT:0518 WriteShuffledPalTriplets.bit2Reset +BOOT:0528 ApplyPaletteOverride +BOOT:0539 ApplyPaletteOverride.copyPalette +BOOT:0564 GetPalettes +BOOT:0566 GetPalettes.copyPalette +BOOT:057b AddPalTripletOffset +BOOT:0582 AddPalTripletOffset.loop +BOOT:0588 AddPalTripletOffset.done +BOOT:0589 PickDMGPalette +BOOT:0596 PickDMGPalette.seekButtonCombo +BOOT:05a0 PickDMGPalette.jumpToDone +BOOT:05a2 PickDMGPalette.buttonComboFound +BOOT:05cf PickDMGPalette.done +BOOT:05d0 SetupCompatibility +BOOT:05de SetupCompatibility.dmgMode +BOOT:05fe SetupCompatibility.tryWriteLogoTilemap +BOOT:0606 SetupCompatibility.done +BOOT:0607 GameBoyLogoTiles +BOOT:06c7 GameBoyLogoTiles.end +BOOT:06c7 TitleChecksums +BOOT:0708 TitleChecksums.ambiguous +BOOT:0716 TitleChecksums.end +BOOT:0716 TitleFourthLetters +BOOT:0724 TitleFourthLetters.row +BOOT:0733 TitleFourthLetters.end +BOOT:0733 PalTripletIDsAndFlags +BOOT:0791 PaletteOffsets +BOOT:07e8 Palettes +BOOT:08d8 BootAnimationColors +BOOT:08e4 BootAnimationColors.end +BOOT:08e4 JoypadCombos +BOOT:08f0 JoypadCombos.end +BOOT:08f0 JoypadCombosTripletIDsAndFlags +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vTileMap +00:98c2 vGameBoyLogoMap +00:9904 vBigNintendoLogoMap +00:99a7 vNintendoLogoMap +01:8000 vTiles +01:8080 vGameBoyLogoTiles +01:8380 vNintendoLogoTiles +01:83e0 vSecondRTile +01:83f0 vNintendoLogoTilesEnd +01:9800 vAttrMap +01:98c2 vGameBoyLogoAttrs +01:9904 vBigNintendoLogoAttrs +01:99a7 vNintendoLogoAttrs +02:d000 wWorkRAM +02:d000 wTitleChecksum +02:d002 wPreventTerminationCounter +02:d003 wHeldButtons +02:d004 wPressedButtons +02:d005 wPaletteOverrideIndex +02:d006 wWhichPalTripletCopy +02:d007 wOldWhichPalTriplet +02:d008 wWhichPalTriplet +02:d009 wPalShufflingFlagsCopy +02:d00a wOldPalShufflingFlags +02:d00b wPalShufflingFlags +02:d300 wZeroBuffer +02:d800 wOBJPalBuffer +02:d840 wOBJPalBuffer.end +02:d840 wBGPalBuffer +02:d880 wBGPalBuffer.end +02:d900 wPalOfsBuffer +02:d95a wPalOfsBuffer.end +02:d960 wPalOfsBuffer.realEnd +02:da00 wPalBuffer +00:ff80 hLogoBuffer +00:fffe hStackBottom diff --git a/boot/dmg.bin b/boot/dmg.bin new file mode 100644 index 0000000..afa0ee4 Binary files /dev/null and b/boot/dmg.bin differ diff --git a/boot/dmg.sym b/boot/dmg.sym new file mode 100644 index 0000000..d583a47 --- /dev/null +++ b/boot/dmg.sym @@ -0,0 +1,42 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0007 EntryPoint.clearVRAM +BOOT:0027 EntryPoint.decompressLogo +BOOT:0039 EntryPoint.copyRTile +BOOT:0048 EntryPoint.writeTilemapRow +BOOT:004a EntryPoint.writeTilemapByte +BOOT:0055 ScrollLogo +BOOT:0060 ScrollLogo.loop +BOOT:0062 ScrollLogo.delayFrames +BOOT:0064 ScrollLogo.waitVBlank +BOOT:0080 ScrollLogo.playSound +BOOT:0086 ScrollLogo.dontPlaySound +BOOT:0095 DecompressFirstNibble +BOOT:0096 DecompressSecondNibble +BOOT:0098 DecompressSecondNibble.loop +BOOT:00a8 Logo +BOOT:00d8 RTile +BOOT:00e0 CheckLogo +BOOT:00e6 CheckLogo.compare +BOOT:00e9 CheckLogo.logoFailure +BOOT:00f4 CheckLogo.computeChecksum +BOOT:00fa CheckLogo.checksumFailure +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vMainTilemap +00:fffe hStackBottom diff --git a/boot/dmg0.bin b/boot/dmg0.bin new file mode 100644 index 0000000..a558044 Binary files /dev/null and b/boot/dmg0.bin differ diff --git a/boot/dmg0.sym b/boot/dmg0.sym new file mode 100644 index 0000000..463d7e8 --- /dev/null +++ b/boot/dmg0.sym @@ -0,0 +1,40 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0007 EntryPoint.clearVRAM +BOOT:0028 EntryPoint.checkLogo +BOOT:0036 EntryPoint.computeChecksum +BOOT:0042 EntryPoint.decompressLogo +BOOT:0054 EntryPoint.writeTilemapRow +BOOT:0056 EntryPoint.writeTilemapByte +BOOT:0063 ScrollLogo +BOOT:006e ScrollLogo.loop +BOOT:0083 ScrollLogo.playSound +BOOT:0089 ScrollLogo.dontPlaySound +BOOT:0098 Lockup +BOOT:009c Lockup.loop +BOOT:00a9 DecompressFirstNibble +BOOT:00aa DecompressSecondNibble +BOOT:00ac DecompressSecondNibble.loop +BOOT:00bc DelayFrames +BOOT:00be DelayFrames.loop +BOOT:00cb Logo +BOOT:00fd Done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vMainTilemap +00:fffe hStackBottom diff --git a/boot/mgb.bin b/boot/mgb.bin new file mode 100644 index 0000000..d321b04 Binary files /dev/null and b/boot/mgb.bin differ diff --git a/boot/mgb.sym b/boot/mgb.sym new file mode 100644 index 0000000..d583a47 --- /dev/null +++ b/boot/mgb.sym @@ -0,0 +1,42 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:0007 EntryPoint.clearVRAM +BOOT:0027 EntryPoint.decompressLogo +BOOT:0039 EntryPoint.copyRTile +BOOT:0048 EntryPoint.writeTilemapRow +BOOT:004a EntryPoint.writeTilemapByte +BOOT:0055 ScrollLogo +BOOT:0060 ScrollLogo.loop +BOOT:0062 ScrollLogo.delayFrames +BOOT:0064 ScrollLogo.waitVBlank +BOOT:0080 ScrollLogo.playSound +BOOT:0086 ScrollLogo.dontPlaySound +BOOT:0095 DecompressFirstNibble +BOOT:0096 DecompressSecondNibble +BOOT:0098 DecompressSecondNibble.loop +BOOT:00a8 Logo +BOOT:00d8 RTile +BOOT:00e0 CheckLogo +BOOT:00e6 CheckLogo.compare +BOOT:00e9 CheckLogo.logoFailure +BOOT:00f4 CheckLogo.computeChecksum +BOOT:00fa CheckLogo.checksumFailure +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vMainTilemap +00:fffe hStackBottom diff --git a/boot/sgb.bin b/boot/sgb.bin new file mode 100644 index 0000000..2bece74 Binary files /dev/null and b/boot/sgb.bin differ diff --git a/boot/sgb.sym b/boot/sgb.sym new file mode 100644 index 0000000..f3f52a0 --- /dev/null +++ b/boot/sgb.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:000b EntryPoint.clearVRAM +BOOT:002b EntryPoint.clearBuffer +BOOT:0036 EntryPoint.copyHeader +BOOT:0039 EntryPoint.computeChecksum +BOOT:0052 EntryPoint.decompressHeader +BOOT:0064 EntryPoint.copyRTile +BOOT:0073 EntryPoint.writeTilemapRow +BOOT:0075 EntryPoint.writeTilemapByte +BOOT:0080 SendData +BOOT:0089 SendData.sendPacket +BOOT:0091 SendData.sendByte +BOOT:0095 SendData.sendBit +BOOT:009d SendData.gotBit +BOOT:00c2 Wait4Frames +BOOT:00c4 Wait4Frames.waitVBlank +BOOT:00cc Wait4Frames.wait +BOOT:00d3 DecompressFirstNibble +BOOT:00d4 DecompressSecondNibble +BOOT:00d6 DecompressSecondNibble.decompressBit +BOOT:00e6 RTile +BOOT:00fc Done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vMainTilemap +00:c000 wBuffer +00:c060 wBufferEnd +00:fffe hStackBottom diff --git a/boot/sgb2.bin b/boot/sgb2.bin new file mode 100644 index 0000000..96d22b3 Binary files /dev/null and b/boot/sgb2.bin differ diff --git a/boot/sgb2.sym b/boot/sgb2.sym new file mode 100644 index 0000000..f3f52a0 --- /dev/null +++ b/boot/sgb2.sym @@ -0,0 +1,44 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:000b EntryPoint.clearVRAM +BOOT:002b EntryPoint.clearBuffer +BOOT:0036 EntryPoint.copyHeader +BOOT:0039 EntryPoint.computeChecksum +BOOT:0052 EntryPoint.decompressHeader +BOOT:0064 EntryPoint.copyRTile +BOOT:0073 EntryPoint.writeTilemapRow +BOOT:0075 EntryPoint.writeTilemapByte +BOOT:0080 SendData +BOOT:0089 SendData.sendPacket +BOOT:0091 SendData.sendByte +BOOT:0095 SendData.sendBit +BOOT:009d SendData.gotBit +BOOT:00c2 Wait4Frames +BOOT:00c4 Wait4Frames.waitVBlank +BOOT:00cc Wait4Frames.wait +BOOT:00d3 DecompressFirstNibble +BOOT:00d4 DecompressSecondNibble +BOOT:00d6 DecompressSecondNibble.decompressBit +BOOT:00e6 RTile +BOOT:00fc Done +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:013f HeaderMenufacturer +BOOT:0143 HeaderCGBCompat +BOOT:0144 HeaderNewLicensee +BOOT:0146 HeaderSGBFlag +BOOT:0147 HeaderCartType +BOOT:0148 HeaderROMSize +BOOT:0149 HeaderRAMSize +BOOT:014a HeaderRegionCode +BOOT:014b HeaderOldLicensee +BOOT:014c HeaderROMVersion +BOOT:014d HeaderChecksum +BOOT:014e HeaderGlobalChecksum +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vMainTilemap +00:c000 wBuffer +00:c060 wBufferEnd +00:fffe hStackBottom diff --git a/boot/stadium2.bin b/boot/stadium2.bin new file mode 100644 index 0000000..28e1271 Binary files /dev/null and b/boot/stadium2.bin differ diff --git a/boot/stadium2.sym b/boot/stadium2.sym new file mode 100644 index 0000000..57129fe --- /dev/null +++ b/boot/stadium2.sym @@ -0,0 +1,98 @@ +; File generated by rgblink +BOOT:0000 EntryPoint +BOOT:000c EntryPoint.clearBGPalettes +BOOT:0013 ClearLogoGDMA +BOOT:0018 ClearLogoGDMAEnd +BOOT:0018 ClearLogoTilesGDMA +BOOT:001d RTile +BOOT:0025 Main +BOOT:0025 RTileEnd +BOOT:003c Main.clearOAM +BOOT:0047 Main.processLogo +BOOT:005b Main.copyRTile +BOOT:007f Main.nop +BOOT:0084 Main.lockup +BOOT:0086 ClearVRAM +BOOT:0089 ClearUntilMemBoundary +BOOT:008a ClearUntilMemBoundary.loop +BOOT:0090 Memcpy +BOOT:0097 SetupSound +BOOT:00ad SetupSound.initWaveRAM +BOOT:00b3 DecodeLogoHalf +BOOT:00b5 DecodeLogoHalf.decodeTileQuarter +BOOT:00be DecodeLogoHalf.decodingLeftHalf +BOOT:00cc DecodeLogoHalf.decodingRightHalf +BOOT:00e1 DecodeLogoHalf.goToRightHalf +BOOT:00e3 DecodeLogoHalf.decodingTopHalf +BOOT:00ea WaitVBlank +BOOT:00f0 WaitVBlank.wait +BOOT:0104 HeaderLogo +BOOT:0134 HeaderTitle +BOOT:0150 SetOBJAndBGPals +BOOT:0158 SetOBJAndBGPals.writeOBJPalData +BOOT:0162 SetOBJAndBGPals.writeBGPalData +BOOT:0168 CommitBGPalettes +BOOT:017b DoLogoAnimation +BOOT:018f DoLogoAnimation.writeNintendoLogoMap +BOOT:019a DoLogoAnimation.dontWriteNintendoLogo +BOOT:01b1 DoLogoAnimation.changePaletteRow +BOOT:01b3 DoLogoAnimation.changePaletteBlock +BOOT:01b5 DoLogoAnimation.changePaletteLoop +BOOT:01cf DoLogoAnimation.dontWriteLogoAttrMap +BOOT:01dd DoLogoAnimation.playSFX +BOOT:01e4 DoLogoAnimation.dontAnimateLogo +BOOT:01e4 DoLogoAnimation.dontPlaySFX +BOOT:01f5 DoLogoAnimation.stepAnimation +BOOT:01fa PerformFadeout +BOOT:01fc PerformFadeout.loop +BOOT:021f PerformFadeout.clearLogoArea +BOOT:0222 PerformFadeout.clearLogoTiles +BOOT:022b PerformFadeout.fadePalettes +BOOT:0233 PerformFadeout.fadeColor +BOOT:023b PerformFadeout.redCap +BOOT:024f PerformFadeout.greenCap +BOOT:0265 PerformFadeout.blueCap +BOOT:0270 DecompressFirstNibble +BOOT:0271 DecompressSecondNibble +BOOT:0274 DecompressSecondNibble.decompressBit +BOOT:0284 WriteLogoTilemap +BOOT:028c WriteLogoTilemap.writeRow +BOOT:028e WriteLogoTilemap.writeByte +BOOT:0299 WriteLogoTilemap.done +BOOT:029a SetupGameBoyLogo +BOOT:02a9 SetupGameBoyLogo.copyLogoRow +BOOT:02c8 SetupGameBoyLogo.copyRTile +BOOT:02d6 SetupGameBoyLogo.writeAttrRow +BOOT:02d8 SetupGameBoyLogo.writeAttrByte +BOOT:02eb SetupGameBoyLogo.writeTilemapByte +BOOT:02f3 SetupGameBoyLogo.notFirstRow +BOOT:02fa SetupGameBoyLogo.notSecondRow +BOOT:0306 SetupGameBoyLogo.initBGPalsLoop +BOOT:0320 GameBoyLogoTiles +BOOT:03e0 BootAnimationColors +BOOT:03e0 GameBoyLogoTilesEnd +BOOT:03ec BootAnimationColors.end +00:8000 vBlankTile +00:8010 vLogoTiles +00:8190 vRTile +00:9800 vTileMap +00:98c2 vGameBoyLogoMap +00:9904 vBigNintendoLogoMap +00:99a7 vNintendoLogoMap +01:8000 vTiles +01:8080 vGameBoyLogoTiles +01:8380 vNintendoLogoTiles +01:83e0 vSecondRTile +01:83f0 vNintendoLogoTilesEnd +01:9800 vAttrMap +01:98c2 vGameBoyLogoAttrs +01:9904 vBigNintendoLogoAttrs +01:99a7 vNintendoLogoAttrs +02:d000 wWorkRAM +02:d002 wPreventTerminationCounter +02:d300 wZeroBuffer +02:d800 wOBJPalBuffer +02:d840 wBGPalBuffer +02:d840 wOBJPalBufferEnd +02:d880 wBGPalBufferEnd +00:fffe hStackBottom diff --git a/cpu_instrs/cpu_instrs.gb b/cpu_instrs/cpu_instrs.gb new file mode 100644 index 0000000..7b06221 Binary files /dev/null and b/cpu_instrs/cpu_instrs.gb differ diff --git a/cpu_instrs/individual/01-special.gb b/cpu_instrs/individual/01-special.gb new file mode 100644 index 0000000..ad3e998 Binary files /dev/null and b/cpu_instrs/individual/01-special.gb differ diff --git a/cpu_instrs/individual/02-interrupts.gb b/cpu_instrs/individual/02-interrupts.gb new file mode 100644 index 0000000..2089594 Binary files /dev/null and b/cpu_instrs/individual/02-interrupts.gb differ diff --git a/cpu_instrs/individual/03-op sp,hl.gb b/cpu_instrs/individual/03-op sp,hl.gb new file mode 100644 index 0000000..50b3cc7 Binary files /dev/null and b/cpu_instrs/individual/03-op sp,hl.gb differ diff --git a/cpu_instrs/individual/04-op r,imm.gb b/cpu_instrs/individual/04-op r,imm.gb new file mode 100644 index 0000000..58ca7b8 Binary files /dev/null and b/cpu_instrs/individual/04-op r,imm.gb differ diff --git a/cpu_instrs/individual/05-op rp.gb b/cpu_instrs/individual/05-op rp.gb new file mode 100644 index 0000000..1c19d92 Binary files /dev/null and b/cpu_instrs/individual/05-op rp.gb differ diff --git a/cpu_instrs/individual/06-ld r,r.gb b/cpu_instrs/individual/06-ld r,r.gb new file mode 100644 index 0000000..d497bfd Binary files /dev/null and b/cpu_instrs/individual/06-ld r,r.gb differ diff --git a/cpu_instrs/individual/07-jr,jp,call,ret,rst.gb b/cpu_instrs/individual/07-jr,jp,call,ret,rst.gb new file mode 100644 index 0000000..5c8d20b Binary files /dev/null and b/cpu_instrs/individual/07-jr,jp,call,ret,rst.gb differ diff --git a/cpu_instrs/individual/08-misc instrs.gb b/cpu_instrs/individual/08-misc instrs.gb new file mode 100644 index 0000000..4da139b Binary files /dev/null and b/cpu_instrs/individual/08-misc instrs.gb differ diff --git a/cpu_instrs/individual/09-op r,r.gb b/cpu_instrs/individual/09-op r,r.gb new file mode 100644 index 0000000..e30e6ec Binary files /dev/null and b/cpu_instrs/individual/09-op r,r.gb differ diff --git a/cpu_instrs/individual/10-bit ops.gb b/cpu_instrs/individual/10-bit ops.gb new file mode 100644 index 0000000..8988458 Binary files /dev/null and b/cpu_instrs/individual/10-bit ops.gb differ diff --git a/cpu_instrs/individual/11-op a,(hl).gb b/cpu_instrs/individual/11-op a,(hl).gb new file mode 100644 index 0000000..0634b7f Binary files /dev/null and b/cpu_instrs/individual/11-op a,(hl).gb differ diff --git a/cpu_instrs/readme.txt b/cpu_instrs/readme.txt new file mode 100644 index 0000000..6f94955 --- /dev/null +++ b/cpu_instrs/readme.txt @@ -0,0 +1,119 @@ +Game Boy CPU Instruction Behavior Test +-------------------------------------- +This ROM tests the behavior of all CPU instructions except STOP and the +11 illegal opcodes. The tests are fairly thorough, running instructions +with boundary data and verifying both the result and that other +registers are not modified. Instructions which perform the same +operation on different registers are each tested just as thoroughly, in +case an emulator implements each independently. Some sub-tests take half +minute to complete. + +Failed instructions are listed as + + [CB] opcode + +Some errors cannot of course be diagnosed properly, since the test +framework itself relies on basic instruction behavior being correct. + + +Internal operation +------------------ +The main tests use a framework that runs each instruction in a loop, +varying the register values on input and examining them on output. +Rather than keep a table of correct values, it simply calculates a +CRC-32 checksum of all the output, then compares this with the correct +value. Instructions are divided into several groups, each with a +different set of input values suited for their behavior; for example, +the bit test instructions are fed $01, $02, $04 ... $40, $80, to ensure +each bit is handled properly, while the arithmetic instructions are fed +$01, $0F, $10, $7F, $FF, to exercise carry and half-carry. A few +instructions require a custom test due to their uniqueness. + + +Multi-ROM +--------- +In the main directory is a single ROM which runs all the tests. It +prints a test's number, runs the test, then "ok" if it passes, otherwise +a failure code. Once all tests have completed it either reports that all +tests passed, or prints the number of failed tests. Finally, it makes +several beeps. If a test fails, it can be run on its own by finding the +corresponding ROM in individual/. + +Ths compact format on screen is to avoid having the results scroll off +the top, so the test can be started and allowed to run without having to +constantly monitor the display. + +Currently there is no well-defined way for an emulator test rig to +programatically find the result of the test; contact me if you're trying +to do completely automated testing of your emulator. One simple approach +is to take a screenshot after all tests have run, or even just a +checksum of one, and compare this with a previous run. + + +Failure codes +------------- +Failed tests may print a failure code, and also short description of the +problem. For more information about a failure code, look in the +corresponding source file in source/; the point in the code where +"set_test n" occurs is where that failure code will be generated. +Failure code 1 is a general failure of the test; any further information +will be printed. + +Note that once a sub-test fails, no further tests for that file are run. + + +Console output +-------------- +Information is printed on screen in a way that needs only minimum LCD +support, and won't hang if LCD output isn't supported at all. +Specifically, while polling LY to wait for vblank, it will time out if +it takes too long, so LY always reading back as the same value won't +hang the test. It's also OK if scrolling isn't supported; in this case, +text will appear starting at the top of the screen. + +Everything printed on screen is also sent to the game link port by +writing the character to SB, then writing $81 to SC. This is useful for +tests which print lots of information that scrolls off screen. + + +Source code +----------- +Source code is included for all tests, in source/. It can be used to +build the individual test ROMs. Code for the multi test isn't included +due to the complexity of putting everything together. + +Code is written for the wla-dx assembler. To assemble a particular test, +execute + + wla -o "source_filename.s" test.o + wlalink linkfile test.gb + +Test code uses a common shell framework contained in common/. + + +Internal framework operation +---------------------------- +Tests use a common framework for setting things up, reporting results, +and ending. All files first include "shell.inc", which sets up the ROM +header and shell code, and includes other commonly-used modules. + +One oddity is that test code is first copied to internal RAM at $D000, +then executed there. This allows self-modification, and ensures the code +is executed the same way it is on my devcart, which doesn't have a +rewritable ROM as most do. + +Some macros are used to simplify common tasks: + + Macro Behavior + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + wreg addr,data Writes data to addr using LDH + lda addr Loads byte from addr into A using LDH + sta addr Stores A at addr using LDH + delay n Delays n cycles, where NOP = 1 cycle + delay_msec n Delays n milliseconds + set_test n,"Cause" Sets failure code and optional string + +Routines and macros are documented where they are defined. + +-- +Shay Green diff --git a/cpu_instrs/source/01-special.s b/cpu_instrs/source/01-special.s new file mode 100644 index 0000000..776d685 --- /dev/null +++ b/cpu_instrs/source/01-special.s @@ -0,0 +1,78 @@ +; Tests instructions that don't fit template + +.include "shell.inc" + +main: + set_test 2,"JR negative" + ld a,0 + jp jr_neg + inc a +- inc a + inc a + cp 2 + jp nz,test_failed + jp + +jr_neg: + jr - ++ + + set_test 3,"JR positive" + ld a,0 + jr + + inc a ++ inc a + inc a + cp 2 + jp nz,test_failed + + + set_test 4,"LD PC,HL" + ld hl,+ + ld a,0 + ld pc,hl + inc a ++ inc a + inc a + cp 2 + jp nz,test_failed + + + set_test 5,"POP AF" + ld bc,$1200 +- push bc + pop af + push af + pop de + ld a,c + and $F0 + cp e + jp nz,test_failed + inc b + inc c + jr nz,- + + + set_test 6,"DAA" + ; Test all combinations of A and flags (256*16 total) + ld de,0 +- push de + pop af + daa + + push af + call update_crc + pop hl + ld a,l + call update_crc + + inc d + jr nz,- + + ld a,e + add $10 + ld e,a + jr nz,- + + check_crc $6A9F8D8A + + jp tests_passed diff --git a/cpu_instrs/source/02-interrupts.s b/cpu_instrs/source/02-interrupts.s new file mode 100644 index 0000000..de18b34 --- /dev/null +++ b/cpu_instrs/source/02-interrupts.s @@ -0,0 +1,73 @@ +; Tests DI, EI, and HALT (STOP proved untestable) + +.include "shell.inc" + +main: + wreg IE,$04 + + set_test 2,"EI" + ei + ld bc,0 + push bc + pop bc + inc b + wreg IF,$04 +interrupt_addr: + dec b + jp nz,test_failed + ld hl,sp-2 + ldi a,(hl) + cp interrupt_addr + jp nz,test_failed + lda IF + and $04 + jp nz,test_failed + + set_test 3,"DI" + di + ld bc,0 + push bc + pop bc + wreg IF,$04 + ld hl,sp-2 + ldi a,(hl) + or (hl) + jp nz,test_failed + lda IF + and $04 + jp z,test_failed + + set_test 4,"Timer doesn't work" + wreg TAC,$05 + wreg TIMA,0 + wreg IF,0 + delay 500 + lda IF + delay 500 + and $04 + jp nz,test_failed + delay 500 + lda IF + and $04 + jp z,test_failed + pop af + + set_test 5,"HALT" + wreg TAC,$05 + wreg TIMA,0 + wreg IF,0 + halt ; timer interrupt will exit halt + nop ; avoids DMG bug + lda IF + and $04 + jp z,test_failed + + jp tests_passed + +.bank 0 slot 0 +.org $50 + inc a + ret diff --git a/cpu_instrs/source/03-op sp,hl.s b/cpu_instrs/source/03-op sp,hl.s new file mode 100644 index 0000000..9531d51 --- /dev/null +++ b/cpu_instrs/source/03-op sp,hl.s @@ -0,0 +1,102 @@ +; Tests SP/HL instructions + +;.define PRINT_CHECKSUMS 1 +.include "shell.inc" +.include "instr_test.s" + +instrs: + .byte $33,0,0 ; INC SP + .byte $3B,0,0 ; DEC SP + .byte $39,0,0 ; ADD HL,SP + .byte $F9,0,0 ; LD SP,HL + .byte $E8,$01,0 ; ADD SP,1 + .byte $E8,$FF,0 ; ADD SP,-1 + .byte $F8,$01,0 ; LD HL,SP+1 + .byte $F8,$FF,0 ; LD HL,SP-1 +instrs_end: + +test_instr: + ; C = flags register + ld c,$00 + call test + ld c,$F0 + call test + ret + +test: + ; Go through each value for HL + ld hl,values +hl_loop: + ld e,(hl) + inc hl + ld d,(hl) + inc hl + push hl + + ; Go through each value for SP + ld hl,values +values_loop: + push bc + push de + push hl + + push bc + pop af + + ; Switch stack + ld (temp),sp + ld a,(hl+) + ld h,(hl) + ld l,a +; call print_regs + ld sp,hl + + ; Set registers + ld h,d + ld l,e + ld a,$12 + ld bc,$5691 + ld de,$9ABC + + jp instr +instr_done: + ; Save new SP and switch to yet another stack + ld (temp+2),sp + ld sp,$DF70 + + call checksum_af_bc_de_hl + + ; Checksum SP + ld a,(temp+2) + call update_crc_fast + ld a,(temp+3) + call update_crc_fast + + ldsp temp + + pop hl + pop de + pop bc + inc hl + inc hl + ld a,l + cp taken ; JP NZ,taken + .byte $C3,taken ; JP taken + .byte $CA,taken ; JP Z,taken + .byte $D2,taken ; JP NC,taken + .byte $DA,taken ; JP C,taken + + .byte $C4,taken ; CALL NZ,taken + .byte $CC,taken ; CALL Z,taken + .byte $CD,taken ; CALL taken + .byte $D4,taken ; CALL NC,taken + .byte $DC,taken ; CALL C,taken + + ; RET cond + ; INC A + .byte $C0,$3C,0 ; RET NZ + .byte $C8,$3C,0 ; RET Z + .byte $C9,$3C,0 ; RET + .byte $D0,$3C,0 ; RET NC + .byte $D8,$3C,0 ; RET C + .byte $D9,$3C,0 ; RETI + + ; RST + ; can only easily test this one on devcart + .byte $C7,0,0 ; RST $00 +.ifndef BUILD_DEVCART + .byte $CF,0,0 ; RST $08 + .byte $D7,0,0 ; RST $10 + .byte $DF,0,0 ; RST $18 + .byte $E7,0,0 ; RST $20 + .byte $EF,0,0 ; RST $28 + .byte $F7,0,0 ; RST $30 + .byte $FF,0,0 ; RST $38 +.endif + +instrs_end: + +test_instr: + wreg IE,0 ; disable interrupts, since RETI does EI + + ; Go through all 16 combinations of flags + ld bc,$1200 +- + ; Fill 4 bytes of new stack + ld a,$12 + ld ($DF80-2),a + ld a,$34 + ld ($DF80-3),a + ld a,$56 + ld ($DF80-4),a + ld a,$78 + ld ($DF80-5),a + + ; Set AF + push bc + pop af + + ; Switch to new stack + ld (temp),sp + ld sp,$DF80 + + ; Set return address + ld de,instr+3 + push de + + jp instr +instr_done: + inc a +taken: + di ; RETI enables interrupts + + ; Save new SP and switch to yet another stack + ld (temp+2),sp + ld sp,$DF70 + + ; Checksum A and SP + call update_crc_fast + ld a,(temp+2) + call update_crc_fast + ld a,(temp+3) + call update_crc_fast + + ; Checksum 4 bytes of stack + ld a,($DF80-2) + call update_crc_fast + ld a,($DF80-3) + call update_crc_fast + ld a,($DF80-4) + call update_crc_fast + ld a,($DF80-5) + call update_crc_fast + + ldsp temp + + ld a,c + add $10 + ld c,a + jr nz,- + + ret + +checksums: + .byte $EC,$A4,$94,$79,$C4,$00,$96,$2C,$C4,$64,$90,$33,$77,$C7,$0A,$D4 + .byte $77,$A3,$0C,$CB,$79,$E7,$7E,$AE,$DA,$DC,$03,$F7,$4F,$9F,$E9,$20 + .byte $72,$12,$DA,$01,$44,$6A,$4D,$8F,$D1,$79,$30,$4C,$AA,$37,$F2,$6A + .byte $97,$EA,$56,$5F,$32,$28,$C7,$D1,$49,$66,$05,$F7,$80,$0F,$BA,$8E + .byte $41,$E2,$A4,$9A,$2D,$2D,$8C,$72,$A5,$13,$76,$A8,$64,$FE,$68,$BC + .byte $2D,$2D,$8C,$72,$50,$96,$24,$27,$50,$96,$24,$27,$50,$96,$24,$27 + .byte $50,$96,$24,$27,$50,$96,$24,$27,$50,$96,$24,$27,$50,$96,$24,$27 + .byte $50,$96,$24,$27 + +.include "multi_custom.s" diff --git a/cpu_instrs/source/08-misc instrs.s b/cpu_instrs/source/08-misc instrs.s new file mode 100644 index 0000000..5c11c8e --- /dev/null +++ b/cpu_instrs/source/08-misc instrs.s @@ -0,0 +1,110 @@ +; Tests miscellaneous instructions + +;.define PRINT_CHECKSUMS 1 +.include "shell.inc" +.include "instr_test.s" + +instrs: + .byte $F0,$91,0 ; LDH A,($91) + .byte $E0,$91,0 ; LDH ($91),A + .byte $F2,$00,0 ; LDH A,(C) + .byte $E2,$00,0 ; LDH (C),A + .byte $FA,$91,$FF ; LD A,($FF91) + .byte $EA,$91,$FF ; LD ($FF91),A + .byte $08,$91,$FF ; LD ($FF91),SP + .byte $01,$23,$01 ; LD BC,$0123 + .byte $11,$23,$01 ; LD DE,$0123 + .byte $21,$23,$01 ; LD HL,$0123 + .byte $31,$23,$01 ; LD SP,$0123 + .byte $F5,0,0 ; PUSH AF + .byte $C5,0,0 ; PUSH BC + .byte $D5,0,0 ; PUSH DE + .byte $E5,0,0 ; PUSH HL + .byte $F1,0,0 ; POP AF + .byte $C1,0,0 ; POP BC + .byte $D1,0,0 ; POP DE + .byte $E1,0,0 ; POP HL +instrs_end: + +test_instr: + ; C = flags register + ld c,$00 + call test + ld c,$10 + call test + ld c,$E0 + call test + ld c,$F0 + call test + ret + +test: + ; Fill RAM + ld a,$FE + ld ($FF90),a + ld a,$DC + ld ($FF91),a + ld a,$BA + ld ($FF92),a + + ; Fill stack + ld a,$13 + ld ($DF80),a + ld a,$57 + ld ($DF80-1),a + ld a,$9B + ld ($DF80-2),a + ld a,$DF + ld ($DF80-3),a + + ; Set registers + ld b,$12 + push bc + ld bc,$5691 + ld de,$9ABC + ld hl,$DEF0 + pop af + + ; Switch stack + ld (temp),sp + ld sp,$DF80-2 + + jp instr +instr_done: + ; Save new SP and switch to another stack + ld (temp+2),sp + ld sp,$DF70 + + call checksum_af_bc_de_hl + + ; Checksum SP + ld a,(temp+2) + call update_crc_fast + ld a,(temp+3) + call update_crc_fast + + ; Checksum RAM + ld a,($FF90) + call update_crc_fast + ld a,($FF91) + call update_crc_fast + ld a,($FF92) + call update_crc_fast + + ; Checksum stack + ld a,($DF80) + call update_crc_fast + ld a,($DF80-1) + call update_crc_fast + ld a,($DF80-2) + call update_crc_fast + ld a,($DF80-3) + call update_crc_fast + + ; Restore SP + ldsp temp + + ret + +checksums: + .byte $4D,$FF,$15,$97,$6D,$A7,$35,$65,$4D,$FF,$15,$97,$6D,$A7,$35,$65,$4D,$FF,$15,$97,$6D,$A7,$35,$65,$AD,$FA,$5E,$41,$D0,$78,$79,$C1,$AF,$66,$99,$34,$0D,$E1,$97,$99,$6F,$D0,$6F,$5D,$C3,$1F,$A3,$8A,$C2,$F1,$9C,$F3,$C1,$C3,$DC,$78,$C0,$2D,$E3,$01,$8F,$C4,$0F,$44,$95,$22,$6A,$39,$61,$C5,$AB,$55,$FB,$DF,$2C,$52, diff --git a/cpu_instrs/source/09-op r,r.s b/cpu_instrs/source/09-op r,r.s new file mode 100644 index 0000000..432c4e7 --- /dev/null +++ b/cpu_instrs/source/09-op r,r.s @@ -0,0 +1,269 @@ +; Tests most register instructions. +; Takes 10 seconds. + +;.define PRINT_CHECKSUMS 1 +.include "shell.inc" +.include "instr_test.s" + +instrs: + .byte $00,0,0 ; NOP + .byte $2F,0,0 ; CPL + .byte $37,0,0 ; SCF + .byte $3F,0,0 ; CCF + + .byte $B0,0,0 ; OR B + .byte $B1,0,0 ; OR C + .byte $B2,0,0 ; OR D + .byte $B3,0,0 ; OR E + .byte $B4,0,0 ; OR H + .byte $B5,0,0 ; OR L + .byte $B7,0,0 ; OR A + + .byte $B8,0,0 ; CP B + .byte $B9,0,0 ; CP C + .byte $BA,0,0 ; CP D + .byte $BB,0,0 ; CP E + .byte $BC,0,0 ; CP H + .byte $BD,0,0 ; CP L + .byte $BF,0,0 ; CP A + + .byte $80,0,0 ; ADD B + .byte $81,0,0 ; ADD C + .byte $82,0,0 ; ADD D + .byte $83,0,0 ; ADD E + .byte $84,0,0 ; ADD H + .byte $85,0,0 ; ADD L + .byte $87,0,0 ; ADD A + + .byte $88,0,0 ; ADC B + .byte $89,0,0 ; ADC C + .byte $8A,0,0 ; ADC D + .byte $8B,0,0 ; ADC E + .byte $8C,0,0 ; ADC H + .byte $8D,0,0 ; ADC L + .byte $8F,0,0 ; ADC A + + .byte $90,0,0 ; SUB B + .byte $91,0,0 ; SUB C + .byte $92,0,0 ; SUB D + .byte $93,0,0 ; SUB E + .byte $94,0,0 ; SUB H + .byte $95,0,0 ; SUB L + .byte $97,0,0 ; SUB A + + .byte $98,0,0 ; SBC B + .byte $99,0,0 ; SBC C + .byte $9A,0,0 ; SBC D + .byte $9B,0,0 ; SBC E + .byte $9C,0,0 ; SBC H + .byte $9D,0,0 ; SBC L + .byte $9F,0,0 ; SBC A + + .byte $A0,0,0 ; AND B + .byte $A1,0,0 ; AND C + .byte $A2,0,0 ; AND D + .byte $A3,0,0 ; AND E + .byte $A4,0,0 ; AND H + .byte $A5,0,0 ; AND L + .byte $A7,0,0 ; AND A + + .byte $A8,0,0 ; XOR B + .byte $A9,0,0 ; XOR C + .byte $AA,0,0 ; XOR D + .byte $AB,0,0 ; XOR E + .byte $AC,0,0 ; XOR H + .byte $AD,0,0 ; XOR L + .byte $AF,0,0 ; XOR A + + .byte $05,0,0 ; DEC B + .byte $0D,0,0 ; DEC C + .byte $15,0,0 ; DEC D + .byte $1D,0,0 ; DEC E + .byte $25,0,0 ; DEC H + .byte $2D,0,0 ; DEC L + .byte $3D,0,0 ; DEC A + + .byte $04,0,0 ; INC B + .byte $0C,0,0 ; INC C + .byte $14,0,0 ; INC D + .byte $1C,0,0 ; INC E + .byte $24,0,0 ; INC H + .byte $2C,0,0 ; INC L + .byte $3C,0,0 ; INC A + + .byte $07,0,0 ; RLCA + .byte $17,0,0 ; RLA + .byte $0F,0,0 ; RRCA + .byte $1F,0,0 ; RRA + + .byte $CB,$00,0 ; RLC B + .byte $CB,$01,0 ; RLC C + .byte $CB,$02,0 ; RLC D + .byte $CB,$03,0 ; RLC E + .byte $CB,$04,0 ; RLC H + .byte $CB,$05,0 ; RLC L + .byte $CB,$07,0 ; RLC A + + .byte $CB,$08,0 ; RRC B + .byte $CB,$09,0 ; RRC C + .byte $CB,$0A,0 ; RRC D + .byte $CB,$0B,0 ; RRC E + .byte $CB,$0C,0 ; RRC H + .byte $CB,$0D,0 ; RRC L + .byte $CB,$0F,0 ; RRC A + + .byte $CB,$10,0 ; RL B + .byte $CB,$11,0 ; RL C + .byte $CB,$12,0 ; RL D + .byte $CB,$13,0 ; RL E + .byte $CB,$14,0 ; RL H + .byte $CB,$15,0 ; RL L + .byte $CB,$17,0 ; RL A + + .byte $CB,$18,0 ; RR B + .byte $CB,$19,0 ; RR C + .byte $CB,$1A,0 ; RR D + .byte $CB,$1B,0 ; RR E + .byte $CB,$1C,0 ; RR H + .byte $CB,$1D,0 ; RR L + .byte $CB,$1F,0 ; RR A + + .byte $CB,$20,0 ; SLA B + .byte $CB,$21,0 ; SLA C + .byte $CB,$22,0 ; SLA D + .byte $CB,$23,0 ; SLA E + .byte $CB,$24,0 ; SLA H + .byte $CB,$25,0 ; SLA L + .byte $CB,$27,0 ; SLA A + + .byte $CB,$28,0 ; SRA B + .byte $CB,$29,0 ; SRA C + .byte $CB,$2A,0 ; SRA D + .byte $CB,$2B,0 ; SRA E + .byte $CB,$2C,0 ; SRA H + .byte $CB,$2D,0 ; SRA L + .byte $CB,$2F,0 ; SRA A + + .byte $CB,$30,0 ; SWAP B + .byte $CB,$31,0 ; SWAP C + .byte $CB,$32,0 ; SWAP D + .byte $CB,$33,0 ; SWAP E + .byte $CB,$34,0 ; SWAP H + .byte $CB,$35,0 ; SWAP L + .byte $CB,$37,0 ; SWAP A + + .byte $CB,$38,0 ; SRL B + .byte $CB,$39,0 ; SRL C + .byte $CB,$3A,0 ; SRL D + .byte $CB,$3B,0 ; SRL E + .byte $CB,$3C,0 ; SRL H + .byte $CB,$3D,0 ; SRL L + .byte $CB,$3F,0 ; SRL A +instrs_end: + +test_instr: + ld c,$00 + call test + ld c,$F0 + call test + ret + +test: + ; Go through each value for A + ld hl,values +a_loop: + ld b,(hl) + push hl + + ; Go through each value for other registers + ld hl,values +values_loop: + push bc + push hl + + push bc + + ; BC + ld a,(hl+) + ld b,a + ld a,(hl+) + ld c,a + + ; HL + ld a,(hl+) + ld d,a + ld a,(hl+) + ld e,a + push de + + ; DE + ld a,(hl+) + ld d,a + ld a,(hl+) + ld e,a + + pop hl + pop af + +; call print_regs + jp instr +instr_done: + + ; Checksum registers + call checksum_af_bc_de_hl + + pop hl + pop bc + inc hl + ld a,l + cp checksums + ld (next_checksum+1),a + ret + +; Compares current checksum with next checksum in +; list. Z if they match, NZ if not. +; Preserved: BC, DE, HL +checksums_compare: +.ifdef PRINT_CHECKSUMS + lda checksum+3 + push af + lda checksum+2 + push af + lda checksum+1 + push af + lda checksum+0 + push af + + ld a,(next_checksum) + inc a + ld (next_checksum),a + sub BGMAP0) >> 2 + add hl,hl + add hl,hl + + ; Copy line + ld de,console_buf + console_width +- dec e + ld a,(de) + ldi (hl),a + ld a,e + cp checksum + ldi (hl),a + ld (hl),d + inc l + ld (hl),c + inc l + ld (hl),b + + pop hl + pop de + pop bc + pop af + ret diff --git a/cpu_instrs/source/common/crc_fast.s b/cpu_instrs/source/common/crc_fast.s new file mode 100644 index 0000000..d1088b0 --- /dev/null +++ b/cpu_instrs/source/common/crc_fast.s @@ -0,0 +1,88 @@ +; Fast table-based CRC-32 + +.define crc_tables (bss+$FF)&$FF00 ; 256-byte aligned +.redefine bss crc_tables+$400 + + +; Initializes fast CRC tables and resets checksum. +; Time: 47 msec +init_crc_fast: + ld l,0 +@next: + xor a + ld c,a + ld d,a + ld e,l + + ld h,8 +- rra + rr c + rr d + rr e + jr nc,+ + xor $ED + ld b,a + ld a,c + xor $B8 + ld c,a + ld a,d + xor $83 + ld d,a + ld a,e + xor $20 + ld e,a + ld a,b + ++ dec h + jr nz,- + + ld h,>crc_tables + ld (hl),e + inc h + ld (hl),d + inc h + ld (hl),c + inc h + ld (hl),a + + inc l + jr nz,@next + + jp init_crc + + +; Faster version of update_crc +; Preserved: BC, DE +; Time: 50 cycles (including CALL) +update_crc_fast: + +; Fastest inline macro version of update_crc_fast +; Time: 40 cycles +; Size: 28 bytes +.macro update_crc_fast + ld l,a ; 1 + lda checksum ; 3 + xor l ; 1 + ld l,a ; 1 + ld h,>crc_tables ; 2 + + lda checksum+1 ; 3 + xor (hl) ; 2 + inc h ; 1 + sta checksum ; 3 + + lda checksum+2 ; 3 + xor (hl) ; 2 + inc h ; 1 + sta checksum+1 ; 3 + + lda checksum+3 ; 3 + xor (hl) ; 2 + inc h ; 1 + sta checksum+2 ; 3 + + ld a,(hl) ; 2 + sta checksum+3 ; 3 +.endm + update_crc_fast + ret diff --git a/cpu_instrs/source/common/delay.s b/cpu_instrs/source/common/delay.s new file mode 100644 index 0000000..65eb9c0 --- /dev/null +++ b/cpu_instrs/source/common/delay.s @@ -0,0 +1,220 @@ +; Delays in cycles, milliseconds, etc. + +; All routines are re-entrant (no global data). Routines never +; touch BC, DE, or HL registers. These ASSUME CPU is at normal +; speed. If running at double speed, msec/usec delays are half advertised. + +; Delays n cycles, from 0 to 16777215 +; Preserved: AF, BC, DE, HL +.macro delay ARGS n + .if n < 0 + .printt "Delay must be >= 0" + .fail + .endif + .if n > 16777215 + .printt "Delay must be < 16777216" + .fail + .endif + delay_ n&$FFFF, n>>16 +.endm + +; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. +; Preserved: AF, BC, DE, HL +.macro delay_clocks ARGS n + .if n # 4 != 0 + .printt "Delay must be a multiple of 4" + .fail + .endif + delay_ (n/4)&$FFFF,(n/4)>>16 +.endm + +; Delays n microseconds (1/1000000 second) +; n can range from 0 to 4000 usec. +; Preserved: AF, BC, DE, HL +.macro delay_usec ARGS n + .if n < 0 + .printt "Delay must be >= 0" + .fail + .endif + .if n > 4000 + .printt "Delay must be <= 4000 usec" + .fail + .endif + delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 +.endm + +; Delays n milliseconds (1/1000 second) +; n can range from 0 to 10000 msec. +; Preserved: AF, BC, DE, HL +.macro delay_msec ARGS n + .if n < 0 + .printt "Delay must be >= 0" + .fail + .endif + .if n > 10000 + .printt "Delay must be <= 10000 msec" + .fail + .endif + delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 +.endm + + ; All the low/high quantities are to deal wla-dx's asinine + ; restriction full expressions must evaluate to a 16-bit + ; value. If the author ever rectifies this, all "high" + ; arguments can be treated as zero and removed. Better yet, + ; I'll just find an assembler that didn't crawl out of + ; the sewer (this is one of too many bugs I've wasted + ; hours working around). + + .define max_short_delay 28 + + .macro delay_long_ ARGS n, high + ; 0+ to avoid assembler treating as memory read + ld a,0+(((high<<16)+n) - 11) >> 16 + call delay_65536a_9_cycles_ + delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 + .endm + + ; Doesn't save AF, allowing minimization of AF save/restore + .macro delay_nosave_ ARGS n, high + ; 65536+11 = maximum delay using delay_256a_9_cycles_ + ; 255+22 = maximum delay using delay_a_20_cycles + ; 22 = minimum delay using delay_a_20_cycles + .if high > 1 + delay_long_ n, high + .else + .if high*n > 11 + delay_long_ n, high + .else + .if (high*(255+22+1))|n > 255+22 + ld a,>(((high<<16)+n) - 11) + call delay_256a_9_cycles_ + delay_nosave_ <(((high<<16)+n) - 11), 0 + .else + .if n >= 22 + ld a,n - 22 + call delay_a_20_cycles + .else + delay_short_ n + .endif + .endif + .endif + .endif + .endm + + .macro delay_ ARGS low, high + .if (high*(max_short_delay+1))|low > max_short_delay + push af + delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 + pop af + .else + delay_short_ low + .endif + .endm + + +; Delays A cycles + overhead +; Preserved: BC, DE, HL +; Time: A+20 cycles (including CALL) +delay_a_20_cycles: +- sub 5 ; 2 + jr nc,- ;3/2 do multiples of 5 + rra ; 1 + jr nc,+ ;3/2 bit 0 ++ adc 1 ; 2 + ret nc ;5/2 -1: 0 cycles + ret z ;5/2 0: 2 cycles + nop ; 1 1: 4 cycles + ret ; 4 (thanks to dclxvi for original algorithm) + +; Delays A*256 cycles + overhead +; Preserved: BC, DE, HL +; Time: A*256+12 cycles (including CALL) +delay_256a_12_cycles: + or a ; 1 + ret z ; 5/2 +delay_256a_9_cycles_: +- delay 256-4 + dec a ; 1 + jr nz,- ;3/2 + ret ; 4 + +; Delays A*65536 cycles + overhead +; Preserved: BC, DE, HL +; Time: A*65536+12 cycles (including CALL) +delay_65536a_12_cycles: + or a ; 1 + ret z ;5/2 +delay_65536a_9_cycles_: +- delay 65536-4 + dec a ; 1 + jr nz,- ;3/2 + ret ; 4 + +; Delays H*256+L cycles + overhead +; Preserved: AF, BC, DE, HL +; Time: H*256+L+51 cycles +delay_hl_51_cycles: + push af + ld a,h + call delay_256a_12_cycles + ld a,l + call delay_a_20_cycles + pop af + ret + + ; delay_short_ macro calls into these + .ds max_short_delay-10,$00 ; NOP repeated several times +delay_unrolled_: + ret + +.macro delay_short_ ARGS n + .if n < 0 + .fail + .endif + .if n > max_short_delay + .fail + .endif + + .if n == 1 + nop + .endif + .if n == 2 + nop + nop + .endif + .if n == 3 + .byte $18,$00 ; JR +0 + .endif + .if n == 4 + .byte $18,$00 ; JR +0 + nop + .endif + .if n == 5 + .byte $18,$00 ; JR +0 + nop + nop + .endif + .if n == 6 + .byte $18,$00 ; JR +0 + .byte $18,$00 ; JR +0 + .endif + .if n == 7 + push af + pop af + .endif + .if n == 8 + push af + pop af + nop + .endif + .if n == 9 + push af + pop af + nop + nop + .endif + .if n >= 10 + call delay_unrolled_ + 10 - n + .endif +.endm diff --git a/cpu_instrs/source/common/gb.inc b/cpu_instrs/source/common/gb.inc new file mode 100644 index 0000000..31bbf14 --- /dev/null +++ b/cpu_instrs/source/common/gb.inc @@ -0,0 +1,64 @@ +; Game Boy hardware addresses + +; Memory +.define VRAM $8000 ; video memory +.define TILES $8000 ; tile images +.define BGMAP0 $9800 ; first 32x32 tilemap +.define BGMAP1 $9C00 ; second 32x32 tilemap +.define WRAM $C000 ; internal memory +.define OAM $FE00 ; sprite memory +.define HRAM $FF80 ; fast memory for LDH + +.define P1 $FF00 + +; Game link I/O +.define SB $FF01 +.define SC $FF02 + +; Interrupts +.define DIV $FF04 +.define TIMA $FF05 +.define TMA $FF06 +.define TAC $FF07 +.define IF $FF0F +.define IE $FFFF + +; LCD registers +.define LCDC $FF40 ; control +.define STAT $FF41 ; status +.define SCY $FF42 ; scroll Y +.define SCX $FF43 ; scroll X +.define LY $FF44 ; current Y being rendered +.define BGP $FF47 + +.define KEY1 $FF4D ; for changing CPU speed +.define VBK $FF4F + +; Sound registers +.define NR10 $FF10 +.define NR11 $FF11 +.define NR12 $FF12 +.define NR13 $FF13 +.define NR14 $FF14 + +.define NR21 $FF16 +.define NR22 $FF17 +.define NR23 $FF18 +.define NR24 $FF19 + +.define NR30 $FF1A +.define NR31 $FF1B +.define NR32 $FF1C +.define NR33 $FF1D +.define NR34 $FF1E + +.define NR41 $FF20 +.define NR42 $FF21 +.define NR43 $FF22 +.define NR44 $FF23 + +.define NR50 $FF24 +.define NR51 $FF25 +.define NR52 $FF26 + +.define WAVE $FF30 diff --git a/cpu_instrs/source/common/instr_test.s b/cpu_instrs/source/common/instr_test.s new file mode 100644 index 0000000..5ed6e2c --- /dev/null +++ b/cpu_instrs/source/common/instr_test.s @@ -0,0 +1,105 @@ +; Framework for CPU instruction tests + +; Calls test_instr with each instruction copied +; to instr, with a JP instr_done after it. +; Verifies checksum after testing instruction and +; prints opcode if it's wrong. + +.include "checksums.s" +.include "cpu_speed.s" +.include "apu.s" +.include "crc_fast.s" + +.define instr $DEF8 +.define rp_temp (instr-4) + +.define temp bss + +; Sets SP to word at addr +; Preserved: BC, DE +.macro ldsp ; addr + ld a,(\1) + ld l,a + ld a,((\1)+1) + ld h,a + ld sp,hl +.endm + +main: + call cpu_fast + call init_crc_fast + call checksums_init + set_test 0 + + ld hl,instrs +- ; Copy instruction + ld a,(hl+) + ld (instr),a + ld a,(hl+) + ld (instr+1),a + ld a,(hl+) + ld (instr+2),a + push hl + + ; Put JP instr_done after it + ld a,$C3 + ld (instr+3),a + ld a,instr_done + ld (instr+5),a + + call reset_crc + call test_instr + + call checksums_compare + jr z,passed + + set_test 1 + ld a,(instr) + call print_a + cp $CB + jr nz,+ + ld a,(instr+1) + call print_a ++ + +passed: + ; Next instruction + pop hl + ld a,l + cp instrs_end + jr nz,- + + jp tests_done + + +; Updates checksum with AF, BC, DE, and HL +checksum_af_bc_de_hl: + push hl + + push af + update_crc_fast + pop hl + ld a,l + update_crc_fast + + ld a,b + update_crc_fast + ld a,c + update_crc_fast + + ld a,d + update_crc_fast + ld a,e + update_crc_fast + + pop de + ld a,d + update_crc_fast + ld a,e + update_crc_fast + ret diff --git a/cpu_instrs/source/common/macros.inc b/cpu_instrs/source/common/macros.inc new file mode 100644 index 0000000..c413bd5 --- /dev/null +++ b/cpu_instrs/source/common/macros.inc @@ -0,0 +1,73 @@ +; General macros + +; Reads A from addr, from $FF00 to $FFFF +; Preserved: F, BC, DE, HL +; Time: 3 cycles +.macro lda ARGS addr + ldh a,(addr - $FF00) +.endm + +; Writes A to addr, from $FF00 to $FFFF +; Preserved: AF, BC, DE, HL +; Time: 3 cycles +.macro sta ARGS addr + ldh (addr - $FF00),a +.endm + +; Writes immediate data to addr, from $FF00 to $FFFF +; Preserved: F, BC, DE, HL +; Time: 5 cycles +.macro wreg ARGS addr, data + ld a,data + sta addr +.endm + +; Calls routine multiple times, with A having the +; value 'start' the first time, 'start+step' the +; second time, up to 'end' for the last time. +; Preserved: BC, DE, HL +.macro for_loop ; routine,start,end,step + ld a,\2 + +for_loop\@: + push af + call \1 + pop af + + add \4 + cp <(\3 + \4) + jr nz,for_loop\@ +.endm + +; Calls routine n times. The value of A in the routine +; counts from 0 to n-1. +; Preserved: BC, DE, HL +.macro loop_n_times ; routine,n + for_loop \1,0,\2 - 1,+1 +.endm + +; Same as for_loop, but counts with 16-bit value in BC. +; Preserved: DE, HL +.macro for_loop16 ; routine,start,end,step + ld bc,\2 + +for_loop16\@: + push bc + call \1 + pop bc + + ld a,c + add <\4 + ld c,a + + ld a,b + adc >\4 + ld b,a + + cp >(\3+\4) + jr nz,for_loop16\@ + + ld a,c + cp <(\3+\4) + jr nz,for_loop16\@ +.endm diff --git a/cpu_instrs/source/common/multi_custom.s b/cpu_instrs/source/common/multi_custom.s new file mode 100644 index 0000000..4dbae9d --- /dev/null +++ b/cpu_instrs/source/common/multi_custom.s @@ -0,0 +1,38 @@ +; RST handlers +.bank 0 slot 0 +.org 0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret + .ds 6,0 + inc a + ret diff --git a/cpu_instrs/source/common/numbers.s b/cpu_instrs/source/common/numbers.s new file mode 100644 index 0000000..6d6faf8 --- /dev/null +++ b/cpu_instrs/source/common/numbers.s @@ -0,0 +1,177 @@ +; Printing of numeric values + +; Prints value of indicated register/pair +; as 2/4 hex digits, followed by a space. +; Updates checksum with printed values. +; Preserved: AF, BC, DE, HL + +print_regs: + call print_af + call print_bc + call print_de + call print_hl + call print_newline + ret + +print_a: + push af +print_a_: + call print_hex + ld a,' ' + call print_char_nocrc + pop af + ret + +print_af: + push af + call print_hex + pop af +print_f: + push bc + push af + pop bc + call print_c + pop bc + ret + +print_b: + push af + ld a,b + jr print_a_ + +print_c: + push af + ld a,c + jr print_a_ + +print_d: + push af + ld a,d + jr print_a_ + +print_e: + push af + ld a,e + jr print_a_ + +print_h: + push af + ld a,h + jr print_a_ + +print_l: + push af + ld a,l + jr print_a_ + +print_bc: + push af + push bc +print_bc_: + ld a,b + call print_hex + ld a,c + pop bc + jr print_a_ + +print_de: + push af + push bc + ld b,d + ld c,e + jr print_bc_ + +print_hl: + push af + push bc + ld b,h + ld c,l + jr print_bc_ + + +; Prints A as two hex chars and updates checksum +; Preserved: BC, DE, HL +print_hex: + call update_crc +print_hex_nocrc: + push af + swap a + call + + pop af + ++ and $0F + cp 10 + jr c,+ + add 7 ++ add '0' + jp print_char_nocrc + + +; Prints char_nz if Z flag is clear, +; char_z if Z flag is set. +; Preserved: AF, BC, DE, HL +.macro print_nz ARGS char_nz, char_z + push af + ld a,char_nz + jr nz,print_nz\@ + ld a,char_z +print_nz\@: + call print_char + pop af +.endm + + +; Prints char_nc if C flag is clear, +; char_c if C flag is set. +; Preserved: AF, BC, DE, HL +.macro print_nc ARGS char_nc, char_c + push af + ld a,char_nc + jr nz,print_nc\@ + ld a,char_c +print_nc\@: + call print_char + pop af +.endm + + +; Prints A as 2 decimal digits +; Preserved: AF, BC, DE, HL +print_dec2: + push af + push bc + jr + + + +; Prints A as 1-3 digit decimal value +; Preserved: AF, BC, DE, HL +print_dec: + push af + push bc + + cp 10 + jr c,++ + ld c,100 + cp c + call nc,@digit ++ ld c,10 + call @digit +++ add '0' + call print_char + + pop bc + pop af + ret + +@digit: + ld b,'0'-1 +- inc b + sub c + jr nc,- + add c + + ld c,a + ld a,b + call print_char + ld a,c + ret diff --git a/cpu_instrs/source/common/printing.s b/cpu_instrs/source/common/printing.s new file mode 100644 index 0000000..ad9d811 --- /dev/null +++ b/cpu_instrs/source/common/printing.s @@ -0,0 +1,98 @@ +; Main printing routine that checksums and +; prints to output device + +; Character that does equivalent of print_newline +.define newline 10 + +; Prints char without updating checksum +; Preserved: BC, DE, HL +.define print_char_nocrc bss +.redefine bss bss+3 + + +; Initializes printing. HL = print routine +init_printing: + ld a,l + ld (print_char_nocrc+1),a + ld a,h + ld (print_char_nocrc+2),a + jr show_printing + + +; Hides/shows further printing +; Preserved: BC, DE, HL +hide_printing: + ld a,$C9 ; RET + jr + +show_printing: + ld a,$C3 ; JP (nn) ++ ld (print_char_nocrc),a + ret + + +; Prints character and updates checksum UNLESS +; it's a newline. +; Preserved: AF, BC, DE, HL +print_char: + push af + cp newline + call nz,update_crc + call print_char_nocrc + pop af + ret + + +; Prints space. Does NOT update checksum. +; Preserved: AF, BC, DE, HL +print_space: + push af + ld a,' ' + call print_char_nocrc + pop af + ret + + +; Advances to next line. Does NOT update checksum. +; Preserved: AF, BC, DE, HL +print_newline: + push af + ld a,newline + call print_char_nocrc + pop af + ret + + +; Prints immediate string +; Preserved: AF, BC, DE, HL +.macro print_str ; string,string2 + push hl + call print_str_ + .byte \1 + .if NARGS > 1 + .byte \2 + .endif + .if NARGS > 2 + .byte \3 + .endif + .byte 0 + pop hl +.endm + +print_str_: + pop hl + call print_str_hl + jp hl + + +; Prints zero-terminated string pointed to by HL. +; On return, HL points to byte AFTER zero terminator. +; Preserved: AF, BC, DE +print_str_hl: + push af + jr + +- call print_char ++ ldi a,(hl) + or a + jr nz,- + pop af + ret diff --git a/cpu_instrs/source/common/runtime.s b/cpu_instrs/source/common/runtime.s new file mode 100644 index 0000000..90cd24f --- /dev/null +++ b/cpu_instrs/source/common/runtime.s @@ -0,0 +1,142 @@ +; Common routines and runtime + +; Must be defined by target-specific runtime: +; +; init_runtime: ; target-specific inits +; std_print: ; default routine to print char A +; post_exit: ; called at end of std_exit +; report_byte: ; report A to user + +.define RUNTIME_INCLUDED 1 + +.ifndef bss + ; address of next normal variable + .define bss $D800 +.endif + +.ifndef dp + ; address of next direct-page ($FFxx) variable + .define dp $FF80 +.endif + +; DMG/CGB hardware identifier +.define gb_id_cgb $10 ; mask for testing CGB bit +.define gb_id_devcart $04 ; mask for testing "on devcart" bit + +.define gb_id bss +.redefine bss bss+1 + +; Stack is normally here +.define std_stack $DFFF + +; Copies $1000 bytes from HL to $C000, then jumps to it. +; A is preserved for jumped-to code. +copy_to_wram_then_run: + ld b,a + + ld de,$C000 + ld c,$10 +- ldi a,(hl) + ld (de),a + inc e + jr nz,- + inc d + dec c + jr nz,- + + ld a,b + jp $C000 + +.ifndef CUSTOM_RESET + reset: + ; Run code from $C000, as is done on devcart. This + ; ensures minimal difference in how it behaves. + ld hl,$4000 + jp copy_to_wram_then_run + + .bank 1 slot 1 + .org $0 ; otherwise wla pads with lots of zeroes + jp std_reset +.endif + +; Common routines +.include "gb.inc" +.include "macros.inc" +.include "delay.s" +.include "crc.s" +.include "printing.s" +.include "numbers.s" +.include "testing.s" + +; Sets up hardware and runs main +std_reset: + + ; Init hardware + di + ld sp,std_stack + + ; Save DMG/CGB id + ld (gb_id),a + + ; Init hardware + .ifndef BUILD_GBS + wreg TAC,$00 + wreg IF,$00 + wreg IE,$00 + .endif + + wreg NR52,0 ; sound off + wreg NR52,$80 ; sound on + wreg NR51,$FF ; mono + wreg NR50,$77 ; volume + + ; TODO: clear all memory? + + ld hl,std_print + call init_printing + call init_testing + call init_runtime + call reset_crc ; in case init_runtime prints anything + + delay_msec 250 + + ; Run user code + call main + + ; Default is to successful exit + ld a,0 + jp exit + + +; Exits code and reports value of A +exit: + ld sp,std_stack + push af + call + + pop af + jp post_exit + ++ push af + call print_newline + call show_printing + pop af + + ; Report exit status + cp 1 + + ; 0: "" + ret c + + ; 1: "Failed" + jr nz,+ + print_str "Failed",newline + ret + + ; n: "Failed #n" ++ print_str "Failed #" + call print_dec + call print_newline + ret + +; returnOrg puts this code AFTER user code. +.section "runtime" returnOrg diff --git a/cpu_instrs/source/common/testing.s b/cpu_instrs/source/common/testing.s new file mode 100644 index 0000000..c102f78 --- /dev/null +++ b/cpu_instrs/source/common/testing.s @@ -0,0 +1,176 @@ +; Diagnostic and testing utilities + +.define result bss+0 +.define test_name bss+1 +.redefine bss bss+3 + + +; Sets test code and optional error text +; Preserved: AF, BC, DE, HL +.macro set_test ; code[,text[,text2]] + push hl + call set_test_ + jr @set_test\@ + .byte \1 + .if NARGS > 1 + .byte \2 + .endif + .if NARGS > 2 + .byte \3 + .endif + .byte 0 +@set_test\@: + pop hl +.endm + +set_test_: + pop hl + push hl + push af + inc hl + inc hl + ldi a,(hl) + ld (result),a + ld a,l + ld (test_name),a + ld a,h + ld (test_name+1),a + pop af + ret + + +; Initializes testing module +init_testing: + set_test $FF + call init_crc + ret + + +; Reports "Passed", then exits with code 0 +tests_passed: + call print_newline + print_str "Passed" + ld a,0 + jp exit + + +; Reports "Done" if set_test has never been used, +; "Passed" if set_test 0 was last used, or +; failure if set_test n was last used. +tests_done: + ld a,(result) + inc a + jr z,+ + dec a + jr z,tests_passed + jr test_failed ++ print_str "Done" + ld a,0 + jp exit + + +; Reports current error text and exits with result code +test_failed: + ld a,(test_name) + ld l,a + ld a,(test_name+1) + ld h,a + ld a,(hl) + or a + jr z,+ + call print_newline + call print_str_hl + call print_newline ++ + ld a,(result) + cp 1 ; if a = 0 then a = 1 + adc 0 + jp exit + + +; Prints checksum as 8-character hex value +; Preserved: AF, BC, DE, HL +print_crc: + push af + + ; Must read checksum entirely before printing, + ; since printing updates it. + lda checksum + cpl + push af + + lda checksum+1 + cpl + push af + + lda checksum+2 + cpl + push af + + lda checksum+3 + cpl + + call print_hex + pop af + call print_hex + pop af + call print_hex + pop af + call print_a + + pop af + ret + + +; If checksum doesn't match expected, reports failed test. +; Passing 0 just prints checksum. Clears checksum afterwards. +.macro check_crc ARGS crc + .if crc == 0 + call show_printing + call print_newline + call print_crc + .else + ld bc,(crc >> 16) ~ $FFFF + ld de,(crc & $FFFF) ~ $FFFF + call check_crc_ + .endif +.endm + +check_crc_: + lda checksum+0 + cp e + jr nz,+ + + lda checksum+1 + cp d + jr nz,+ + + lda checksum+2 + cp c + jr nz,+ + + lda checksum+3 + cp b + jr nz,+ + + jp reset_crc + ++ call print_crc + jp test_failed + + +; Updates checksum with bytes from addr to addr+size-1 +.macro checksum_mem ARGS addr,size + ld hl,addr + ld bc,size + call checksum_mem_ +.endm + +checksum_mem_: +- ldi a,(hl) + call update_crc + dec bc + ld a,b + or c + jr nz,- + ret diff --git a/cpu_instrs/source/linkfile b/cpu_instrs/source/linkfile new file mode 100644 index 0000000..02a5a2e --- /dev/null +++ b/cpu_instrs/source/linkfile @@ -0,0 +1,2 @@ +[objects] +test.o diff --git a/cpu_instrs/source/shell.inc b/cpu_instrs/source/shell.inc new file mode 100644 index 0000000..277a9b7 --- /dev/null +++ b/cpu_instrs/source/shell.inc @@ -0,0 +1,21 @@ +.incdir "common" + +; GBS music file +.ifdef BUILD_GBS + .include "build_gbs.s" +.endif + +; Devcart +.ifdef BUILD_DEVCART + .include "build_devcart.s" +.endif + +; Sub-test in a multi-test ROM +.ifdef BUILD_MULTI + .include "build_multi.s" +.endif + +; GB ROM (default) +.ifndef RUNTIME_INCLUDED + .include "build_rom.s" +.endif diff --git a/libpng16.dll b/libpng16.dll new file mode 100644 index 0000000..36c2ce2 Binary files /dev/null and b/libpng16.dll differ diff --git a/rgbasm.exe b/rgbasm.exe new file mode 100644 index 0000000..1754a5e Binary files /dev/null and b/rgbasm.exe differ diff --git a/rgbfix.exe b/rgbfix.exe new file mode 100644 index 0000000..de5f6c4 Binary files /dev/null and b/rgbfix.exe differ diff --git a/rgbgfx.exe b/rgbgfx.exe new file mode 100644 index 0000000..6277756 Binary files /dev/null and b/rgbgfx.exe differ diff --git a/rgblink.exe b/rgblink.exe new file mode 100644 index 0000000..1527eec Binary files /dev/null and b/rgblink.exe differ diff --git a/src/main.rs b/src/main.rs index a7fd1df..1565d86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,8 @@ struct CPU { pc: u16, bus: MemoryBus, sp: u16, + boot_rom: Vec, + game_rom: Vec, } const VRAM_BEGIN: usize = 0x8000; const VRAM_END: usize = 0x9FFF; @@ -117,14 +119,14 @@ impl MemoryBus { self.write_byte(address.wrapping_add(1), high); } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum Target { U8Register(TargetRegister), U16Register(TargetU16Register), Address(u16), Immediate(u8) } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum Condition { NZ, // Not Zero Z, // Zero @@ -133,7 +135,7 @@ enum Condition { None } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum LoadTarget{ CopyR8R8(TargetRegister, TargetRegister), CopyR8N8(TargetRegister, u8), @@ -162,6 +164,7 @@ enum LoadTarget{ } +#[derive(Debug)] enum Instruction { ADC(Target), ADD(Target), @@ -208,11 +211,28 @@ enum Instruction { SWAP(Target), XOR(Target), } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum TargetRegister { A, B, C, D, E, H, L, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum TargetU16Register {AF, BC, DE, HL, SP, PC} impl CPU { + + fn init(&mut self) { + let l = self.bus.memory.len(); + println!("{l}"); + println!("CPU init"); + // println!("Boot ROM: {:02X?}", self.boot_rom); + for (address, byte) in self.boot_rom.iter().enumerate() { + self.bus.write_byte(address as u16, *byte); + } + // println!("Game ROM: {:02X?}", self.game_rom); + for (address, byte) in self.game_rom.iter().enumerate() { + if address < 0x100 { continue; } + if address >= 0x4000 { break; } + self.bus.write_byte(address as u16, *byte); + } + + } fn check_condition(&self, condition: Condition) -> bool { match condition { Condition::NZ => !self.registers.f.zero, @@ -1264,11 +1284,23 @@ impl CPU { fn main() { + let boot_rom = std::fs::read("boot/dmg.bin").unwrap(); + let game_rom = std::fs::read("cpu_instrs/cpu_instrs.gb").unwrap(); - let gameboy = CPU{ + let mut gameboy = CPU{ registers:Registers{a:0,b:0,c:0,d:0,e:0,f:FlagsRegister::from(0),h:0,l:0}, pc:0, bus:MemoryBus{ memory: [0xFFu8; 0xFFFF], gpu:GPU{ vram: Vec::with_capacity(VRAM_END-VRAM_BEGIN), tile_set: [[[TilePixelValue::Zero; 8]; 8]; 384] }}, - sp: 0 + sp: 0, + boot_rom, + game_rom, }; + gameboy.init(); + let sp = gameboy.sp; + println!("{sp:?}"); + let f = gameboy.next_instruction(); + println!("{f:?}"); + gameboy.execute(f); + let sp = gameboy.sp; + println!("{sp:?}"); } diff --git a/zlib1.dll b/zlib1.dll new file mode 100644 index 0000000..49cb57d Binary files /dev/null and b/zlib1.dll differ