Version 5.1 - see readme for details.

This commit is contained in:
Dave Bernazzani 2024-05-27 10:17:30 -04:00
parent b7f6a5345d
commit b38eaeb95b
14 changed files with 113 additions and 73 deletions

View File

@ -14,7 +14,7 @@ include $(DEVKITARM)/ds_rules
export TARGET := NINTV-DS
export TOPDIR := $(CURDIR)
export VERSION := 5.0a
export VERSION := 5.1
ICON := -b $(CURDIR)/logo.bmp "NINTV-DS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/NINTV-DS"

Binary file not shown.

View File

@ -41,7 +41,7 @@ Technical Specs :
* ECS emulated with the 2K of 8-bit RAM, Keyboard, extra sound channels, etc.
* Intellivoice emulated for games that take advantage of voice enhancements.
* Up to 8K of extra 8-bit RAM emulated for games like USFC Chess and Land Battle (note, the 2K of ECS 8-bit RAM comes out of this pool).
* Up to 16K Words of extra 16-bit RAM emulated beyond dedicated 8K words of JLP RAM.
* Up to 16K Words of extra 16-bit RAM emulated beyond dedicated 8K words of JLP RAM (so technically 24K Words of 16-bit RAM available to carts)
* Paging on all segments of memory provided the full binary is 1024KB (bytes) or less.
Loading Games :
@ -58,7 +58,7 @@ Controller Types :
-----------------------
* You can select Player 1 controller or Player 2 controller.
* More importantly you can select 'Dual Action A' or 'Dual Action B'
* Dual Action A uses the disc/buttons from Controller 1 and the Keypad for Controller 2 (perfect for AD&D Cloudy Mountain or Tron Deadly Discs)
* Dual Action A uses the disc/buttons from Controller 1 and the Keypad for Controller 2 (perfect for AD&D Cloudy Mountain or Tron Deadly Discs - you can use the NDS ABXY keys to fire arrows/discs)
* Dual Action B uses the disc from Controller 1 and the Buttons/Keypad for Controller 2 (perfect for Astrosmash, Buzz Bombers and any game you move and shoot)
* In configuration you can press the 'X' button to cycle through some common controller mappings or assign your own custom map.
@ -119,6 +119,11 @@ Credits :
--------------------------------------------------------------------------------
History :
--------------------------------------------------------------------------------
V5.1 : 28-May-2024 by wavemotion-dave
* Improved STIC emulation to properly restrict MOBS for both GRAM and GROM to cards 0-63 in FG/BG mode.
* Separate 2K GRAM build - experimental but functional. Use NINTV-DS-2KGRAM (will coexist with the normal NINTV-DS build)
* Minor cleanup and tweaks as time permitted.
V5.0 : 06-Mar-2024 by wavemotion-dave
* New splash screen jingle.
* Boosted audio output by almost 25% so you don't have to max out your DS volume.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -66,8 +66,8 @@ UINT8 backgroundBuffer[160*96] __attribute__ ((aligned (4)));
UINT16 global_frames __attribute__((section(".dtcm"))) = 0;
UINT16 mobBuffers[8][128] __attribute__((section(".dtcm")));
UINT8 fgcolor __attribute__((section(".dtcm"))) = 0;
UINT8 bgcolor __attribute__((section(".dtcm"))) = 0;
UINT8 fgcolor __attribute__((section(".dtcm"))) = 0;
UINT8 bgcolor __attribute__((section(".dtcm"))) = 0;
// Movable objects
MOB mobs[8] __attribute__((section(".dtcm")));
@ -153,8 +153,8 @@ void AY38900::resetProcessor()
//reset the state variables
mode = 0xFF;
bCP1610_PIN_IN_INTRM = TRUE;
bCP1610_PIN_IN_BUSRQ = TRUE;
bCP1610_PIN_IN_INTRM = TRUE;
bCP1610_PIN_IN_BUSRQ = TRUE;
previousDisplayEnabled = TRUE;
displayEnabled = FALSE;
colorStackMode = FALSE;
@ -644,7 +644,27 @@ ITCM_CODE void AY38900::renderMOBs()
UINT16 card = mobs[i].cardNumber;
// If we are double Y, the STIC requires the card be on an even boundary. Without this we get glitches in the ape climbing in D1K/D2K
if (mobs[i].doubleYResolution) card &= 0xFE;
UINT16 firstMemoryLocation = (UINT16)(mobs[i].isGrom ? LOCATION_GROM + (card << 3) : ((card & 0x3F) << 3));
// ------------------------------------------------------------------------------------
// In Color Stack Mode, the MOB location can index any of the full GROM / GRAM tiles.
// In FG/BG mode, it can only index the first 64 tiles of GROM or GRAM. This is all
// according to the STIC documentation:
//
// Bits 9 and 10 of the attribute register (bits 7 and 6 of the card #)
// are ignored when the bitmap comes from GRAM, or when the display is
// in Foreground/Background mode. (This means that only 128 of the 320
// pictures are available when the display is in FGBG mode. GROM cards
// #64 - #255 are unavailable in FGBG mode.)
// ------------------------------------------------------------------------------------
UINT16 firstMemoryLocation = 0x0000;
if (colorStackMode)
{
firstMemoryLocation = (UINT16)(mobs[i].isGrom ? LOCATION_GROM + ((card & 0xFF) << 3) : ((card & GRAM_CARD_MOB_MASK) << 3));
}
else
{
firstMemoryLocation = (UINT16)(mobs[i].isGrom ? LOCATION_GROM + ((card & 0x3F) << 3) : ((card & 0x3F) << 3));
}
//end at this memory location
UINT16 lastMemoryLocation = (UINT16)(firstMemoryLocation + 8);
@ -691,6 +711,12 @@ ITCM_CODE void AY38900::renderMOBs()
}
}
// -------------------------------------------------------------------
// Render the entire Intellivision background according to what mode
// we are in (FG/BG vs ColorStack) and whether we are doing the more
// complicated latched backtab (uses a bit more emulation CPU power
// but is more accurate).
// -------------------------------------------------------------------
ITCM_CODE void AY38900::renderBackground()
{
if (colorStackMode)
@ -746,7 +772,7 @@ ITCM_CODE void AY38900::renderForegroundBackgroundMode()
//get the next card to render
UINT16 nextCard = backtab.peek_direct(i);
UINT16 isGram = (nextCard & 0x0800);
UINT16 memoryLocation = nextCard & 0x01F8;
UINT16 memoryLocation = nextCard & 0x01F8; // Can only index 64 tiles max in FG/BG mode
//render this card only if this card has changed or if the card points to GRAM
//and one of the eight bytes in gram that make up this card have changed
@ -773,7 +799,7 @@ ITCM_CODE void AY38900::renderForegroundBackgroundModeLatched()
//get the next card to render
UINT16 nextCard = backtab.peek_latched(i);
UINT16 isGram = nextCard & 0x0800;
UINT16 memoryLocation = nextCard & 0x01F8;
UINT16 memoryLocation = nextCard & 0x01F8; // Can only index 64 tiles max in FG/BG mode
//render this card only if this card has changed or if the card points to GRAM
//and one of the eight bytes in gram that make up this card have changed
@ -800,7 +826,7 @@ void AY38900::renderForegroundBackgroundModeLatchedForced()
//get the next card to render
UINT16 nextCard = backtab.peek_latched(i);
UINT16 isGram = nextCard & 0x0800;
UINT16 memoryLocation = nextCard & 0x01F8;
UINT16 memoryLocation = nextCard & 0x01F8; // Can only index 64 tiles max in FG/BG mode
fgcolor = (UINT8)((nextCard & 0x0007) | FOREGROUND_BIT);
bgcolor = (UINT8)(((nextCard & 0x2000) >> 11) | ((nextCard & 0x1600) >> 9));
@ -858,7 +884,7 @@ ITCM_CODE void AY38900::renderColorStackMode()
}
UINT16 isGram = (nextCard & 0x0800);
UINT16 memoryLocation = (isGram ? (nextCard & 0x01F8) : (nextCard & 0x07F8));
UINT16 memoryLocation = (isGram ? (nextCard & GRAM_COL_STACK_MASK) : (nextCard & 0x07F8)); // Can index all 256 tiles max in Color Stack mode
if (renderAll || backtab.isDirtyDirect(h) || (isGram && gram->isCardDirty(memoryLocation)))
{
@ -922,12 +948,11 @@ ITCM_CODE void AY38900::renderColorStackModeLatched()
}
UINT16 isGram = (nextCard & 0x0800);
UINT16 memoryLocation = (isGram ? (nextCard & 0x01F8) : (nextCard & 0x07F8));
UINT16 memoryLocation = (isGram ? (nextCard & GRAM_COL_STACK_MASK) : (nextCard & 0x07F8)); // Can index all 256 tiles max in Color Stack mode
if (renderAll || backtab.isDirtyDirect(h) || (isGram && gram->isCardDirty(memoryLocation)))
{
fgcolor = (UINT8)(((nextCard & 0x1000) >> 9) | (nextCard & 0x0007) | FOREGROUND_BIT);
fgcolor = (UINT8)(((nextCard & 0x1000) >> 9) | (nextCard & 0x0007) | FOREGROUND_BIT);
Memory* memory = (isGram ? (Memory*)gram : (Memory*)grom);
UINT16 address = memory->getReadAddress()+memoryLocation;
for (UINT16 j = 0; j < 8; j++)

View File

@ -20,6 +20,7 @@
// ----------------------------------------------------------------------------------
UINT16 stic_memory[0x40] __attribute__((section(".dtcm")));
// Technically the STIC is read-responsive at 0x40-0x7F but we ignore that for now (nothing seems to rely on it)
AY38900_Registers::AY38900_Registers()
: RAM(0x40, 0x0000, 0xFFFF, 0x3FFF)
{}

View File

@ -28,14 +28,14 @@ void GRAM::reset()
for (i = 0; i < GRAM_SIZE; i++)
gram_image[i] = 0;
for (i = 0; i < 0x40; i++)
for (i = 0; i < (GRAM_SIZE>>3); i++)
dirtyCards[i] = TRUE;
}
ITCM_CODE void GRAM::poke(UINT16 location, UINT16 value)
{
if (!enabled) return;
location &= 0x01FF;
location &= GRAM_MASK;
gram_image[location] = (UINT8)value;
dirtyCards[location>>3] = TRUE;
@ -62,5 +62,5 @@ void GRAM::setState(GRAMState *state)
{
for (int i=0; i<GRAM_SIZE; i++) gram_image[i] = state->gram_image[i];
for (int i=0; i<(GRAM_SIZE>>3); i++) dirtyCards[i] = state->dirtyCards[i];
dirtyRAM = TRUE;
dirtyRAM = TRUE; // Force a redraw to be safe
}

View File

@ -14,11 +14,29 @@
#include "RAM.h"
#define GRAM_SIZE 0x0200
#define GRAM_ADDRESS 0x3800 // GRAM base address (mirros handled with READ/WRITE masks below)
#define GRAM_ADDRESS 0x3800
#define GRAM_READ_MASK 0xF9FF
#define GRAM_WRITE_MASK 0x39FF
//#define GRAM_2K // Enable this line if you want to experiment with a 2K GRAM build
#ifdef GRAM_2K
#define GRAM_SIZE 0x0800 // 2K of GRAM is non-standard but possible!
#define GRAM_READ_MASK 0xFFFF // This is what produces the GRAM read aliases due to incomplete address decoding
#define GRAM_WRITE_MASK 0x3FFF // This is what produces the GRAM write aliases due to incomplete address decoding
#define GRAM_MASK 0x07FF // Allows indexing all 2K of GRAM
#define GRAM_COL_STACK_MASK 0x07F8 // Allows for indexing 256 tiles in Color Stack mode
#define GRAM_CARD_MOB_MASK 0xFF // Allows for indexing 256 tiles for MOBs (technically should only be allowed in Color Stack but whatevs...)
#else // Normal 512b GRAM
#define GRAM_SIZE 0x0200 // 512 bytes of GRAM
#define GRAM_READ_MASK 0xF9FF // This is what produces the GRAM read aliases due to incomplete address decoding
#define GRAM_WRITE_MASK 0x39FF // This is what produces the GRAM write aliases due to incomplete address decoding
#define GRAM_MASK 0x01FF // Allows indexing the 512 bytes of GRAM
#define GRAM_COL_STACK_MASK 0x01F8 // Allows for indexing 64 tiles in Color Stack mode
#define GRAM_CARD_MOB_MASK 0x3F // Allows for indexing 64 tiles for MOBs
#endif // GRAM_2K
extern UINT8 gram_image[GRAM_SIZE];
extern UINT8 dirtyCards[GRAM_SIZE>>3];
@ -40,7 +58,7 @@ class GRAM : public RAM
GRAM();
void reset();
inline UINT16 peek(UINT16 location) {return gram_image[location & 0x01FF];}
inline UINT16 peek(UINT16 location) {return gram_image[location & GRAM_MASK];}
void poke(UINT16 location, UINT16 value);
void markClean();

View File

@ -14,8 +14,8 @@
#include "MemoryBus.h"
#include "../nintv-ds.h"
UINT16 MAX_READ_OVERLAPPED_MEMORIES = 2;
UINT16 MAX_WRITE_OVERLAPPED_MEMORIES = 3;
#define MAX_READ_OVERLAPPED_MEMORIES 16 // Good enough for any page-flipping game. This is massive!
#define MAX_WRITE_OVERLAPPED_MEMORIES 17 // Need one extra here to handle the GRAM mirrors up in odd places in ROM
// ----------------------------------------------------------------------------------------------
// We use this class and single object to fill all unused memory locations in the memory map.
@ -40,50 +40,34 @@ public:
} MyUnusedMemory;
// -------------------------------------------------------------------------------
// --------------------------------------------------------------------------
// This is a serious resource hog... it's multiple 16-bit 64k arrays take
// up a significant bit of our RAM... the max overlapped memories is what
// soaks up quite a bit of main RAM. We limit this for older DS hardware
// memories per address location which is sufficient provided we are only
// loading normal ROMs into a stock intellivision with, at most, an intellivoice
// or the JLP cart as the only peripherals... still, this is a strain on the
// older DS-LITE/PHAT. The original BLISS core allowed 16 overlapping memory
// regions (to handle page flipping) which will fit into the DSi but is too
// large for the original DS-LITE/PHAT so for older hardware, we strip down
// to the bare essentials. For the DSi we can allocate more memory and provide
// the full 16 overlapped mapped memories.
// -------------------------------------------------------------------------------
// soaks up quite a bit of main RAM. We use a cost savings technique here
// to reduce the ram required by mapping compressing down to 16-byte chunks.
// This means we can't have finer resolution than 16-bytes for read/write
// which is only an issue for page-flipping hotspots but fortunately all
// programs so far have been well behaved and only write the normal page
// flipping locations in memory. This reduction allows us to use only
// about 1MB of memory vs 10MB and that's worth the tradeoff in resolution.
// --------------------------------------------------------------------------
UINT32 *overlappedMemoryPool = NULL;
MemoryBus::MemoryBus()
{
// -------------------------------------------------------------------------------------
// We swap in a larger memory model for the DSi to handle really complex page flipping
// -------------------------------------------------------------------------------------
if (isDSiMode())
{
MAX_READ_OVERLAPPED_MEMORIES = 16; // Good enough for any page-flipping game. This is massive!
MAX_WRITE_OVERLAPPED_MEMORIES = 17; // Need one extra here to handle the GRAM mirrors up in odd places in ROM
}
else
{
MAX_READ_OVERLAPPED_MEMORIES = 16; // Good enough for almost all games except very large page-flipping games
MAX_WRITE_OVERLAPPED_MEMORIES = 17; // Need one extra here to handle the GRAM mirrors up in odd places in ROM
}
UINT32 size = 1 << (sizeof(UINT16) << 3);
UINT32 i;
writeableMemoryCounts = new UINT8[size];
memset(writeableMemoryCounts, 0, sizeof(UINT8) * size);
writeableMemorySpace = new Memory**[size>>4];
writeableMemorySpace = new Memory**[size>>MEM_DIV];
// ---------------------------------------------------------------------------------------------------------------------------
// We do this rather than allocate piecemeal so we avoid malloc overhead and extra bytes padded (saves almost 500K on DS)
// ---------------------------------------------------------------------------------------------------------------------------
overlappedMemoryPool = new UINT32[(size*(MAX_READ_OVERLAPPED_MEMORIES+MAX_WRITE_OVERLAPPED_MEMORIES))>>4];
overlappedMemoryPool = new UINT32[(size*(MAX_READ_OVERLAPPED_MEMORIES+MAX_WRITE_OVERLAPPED_MEMORIES))>>MEM_DIV];
UINT32 *memPoolPtr = (UINT32 *)overlappedMemoryPool;
for (i = 0; i < size>>4; i++)
for (i = 0; i < size>>MEM_DIV; i++)
{
writeableMemorySpace[i] = (Memory **)memPoolPtr;
for (int j=0; j<MAX_WRITE_OVERLAPPED_MEMORIES; j++)
@ -94,8 +78,8 @@ MemoryBus::MemoryBus()
}
readableMemoryCounts = (UINT16 *) 0x06820000; // Use video memory ... slightly faster and saves main RAM
memset(readableMemoryCounts, 0, sizeof(UINT16) * size);
readableMemorySpace = new Memory**[size>>4];
for (i = 0; i < size>>4; i++)
readableMemorySpace = new Memory**[size>>MEM_DIV];
for (i = 0; i < size>>MEM_DIV; i++)
{
readableMemorySpace[i] = (Memory **)memPoolPtr;
for (int j=0; j<MAX_READ_OVERLAPPED_MEMORIES; j++)
@ -166,7 +150,7 @@ void MemoryBus::addMemory(Memory* m)
FatalError("ERROR MAX READABLE MEM OVERLAP");
return;
}
readableMemorySpace[k>>4][memCount] = m;
readableMemorySpace[k>>MEM_DIV][memCount] = m;
readableMemoryCounts[k]++;
}
}
@ -197,7 +181,7 @@ void MemoryBus::addMemory(Memory* m)
FatalError("ERROR MAX WRITEABLE MEM OVERLAP");
return;
}
writeableMemorySpace[k>>4][memCount] = m;
writeableMemorySpace[k>>MEM_DIV][memCount] = m;
writeableMemoryCounts[k]++;
}
}
@ -245,13 +229,13 @@ void MemoryBus::removeMemory(Memory* m)
UINT16 memCount = readableMemoryCounts[k];
for (UINT16 n = 0; n < memCount; n++)
{
if (readableMemorySpace[k>>4][n] == m)
if (readableMemorySpace[k>>MEM_DIV][n] == m)
{
for (INT32 l = n; l < (memCount-1); l++)
{
readableMemorySpace[k>>4][l] = readableMemorySpace[k>>4][l+1];
readableMemorySpace[k>>MEM_DIV][l] = readableMemorySpace[k>>MEM_DIV][l+1];
}
readableMemorySpace[k>>4][memCount-1] = &MyUnusedMemory;
readableMemorySpace[k>>MEM_DIV][memCount-1] = &MyUnusedMemory;
break;
}
}
@ -282,13 +266,13 @@ void MemoryBus::removeMemory(Memory* m)
UINT16 memCount = writeableMemoryCounts[k];
for (UINT16 n = 0; n < memCount; n++)
{
if (writeableMemorySpace[k>>4][n] == m)
if (writeableMemorySpace[k>>MEM_DIV][n] == m)
{
for (INT32 l = n; l < (memCount-1); l++)
{
writeableMemorySpace[k>>4][l] = writeableMemorySpace[k>>4][l+1];
writeableMemorySpace[k>>MEM_DIV][l] = writeableMemorySpace[k>>MEM_DIV][l+1];
}
writeableMemorySpace[k>>4][memCount-1] = &MyUnusedMemory;
writeableMemorySpace[k>>MEM_DIV][memCount-1] = &MyUnusedMemory;
break;
}
}
@ -325,7 +309,7 @@ ITCM_CODE UINT16 MemoryBus::peek_slow(UINT16 location)
UINT16 value = 0xFFFF;
for (UINT16 i = 0; i < numMemories; i++)
{
value &= readableMemorySpace[location>>4][i]->peek(location);
value &= readableMemorySpace[location>>MEM_DIV][i]->peek(location);
}
return value;
}
@ -339,7 +323,7 @@ ITCM_CODE void MemoryBus::poke(UINT16 location, UINT16 value)
for (UINT16 i = 0; i < numMemories; i++)
{
writeableMemorySpace[location>>4][i]->poke(location, value);
writeableMemorySpace[location>>MEM_DIV][i]->poke(location, value);
}
// For the lower RAM area... keep the "fast memory" updated
@ -362,13 +346,13 @@ void MemoryBus::poke_cheat(UINT16 location, UINT16 value)
for (UINT16 i = 0; i < numMemories; i++)
{
readableMemorySpace[location>>4][i]->poke_cheat(location, value);
readableMemorySpace[location>>MEM_DIV][i]->poke_cheat(location, value);
}
numMemories = writeableMemoryCounts[location];
for (UINT16 i = 0; i < numMemories; i++)
{
writeableMemorySpace[location>>4][i]->poke_cheat(location, value);
writeableMemorySpace[location>>MEM_DIV][i]->poke_cheat(location, value);
}
}

View File

@ -17,6 +17,8 @@
#include "Memory.h"
#include "ROM.h"
#define MEM_DIV 4 // Divide by 16 which gives us 16 byte resolution on memory mapping - good enough and saves us a huge amount of RAM
/**
* Emulates a 64K memory bus which may be composed of 8-bit or 16-bit memory units.
@ -33,7 +35,7 @@ class MemoryBus
void reset();
inline UINT16 peek(UINT16 location) {if (((UINT16 *) 0x06820000)[location] == 1) return readableMemorySpace[location>>4][0]->peek(location); else return peek_slow(location);}
inline UINT16 peek(UINT16 location) {if (((UINT16 *) 0x06820000)[location] == 1) return readableMemorySpace[location>>MEM_DIV][0]->peek(location); else return peek_slow(location);}
UINT16 peek_slow(UINT16 location);
// ------------------------------------------------------------------------------------------------
@ -51,9 +53,9 @@ class MemoryBus
// ------------------------------------------------------
UINT16 peek_slow_and_safe(UINT16 location)
{
if (readableMemorySpace[location>>4])
if (readableMemorySpace[location>>MEM_DIV])
{
if (readableMemorySpace[location>>4][0])
if (readableMemorySpace[location>>MEM_DIV][0])
{
return peek_slow(location);
}

View File

@ -22,7 +22,7 @@ UINT16 inty_8bit_ram[RAM8BIT_SIZE] __attribute__((section(".dtcm"))) = {0}
UINT16 fast_ram16[0x400] __attribute__((section(".dtcm"))) = {0};
UINT16 fast_ram16_idx = 0;
UINT16 slow_ram16_idx = 0;
UINT16 slow_ram8_idx = 0;
UINT16 slow_ram8_idx = 0;
UINT16 *slow_ram8 = (UINT16*)0x06890000; // 6K of 8-bit RAM here (utilizing 12K of VRAM) - used for carts that define extra 8-bit RAM like Chess and Land Battle. We allow this to expand into the 2K section below.
UINT16 *ecs_ram8 = (UINT16*)0x06893000; // 2K of 8-bit ECS RAM (utilizing 4K of VRAM) for the ECS computer peripheral. We do allow the 6K RAM to expand into this area... so non-ECS games can get 8K of 8-bit ram allocated.

View File

@ -18,8 +18,6 @@
#include "nintv-ds.h"
#include "savestate.h"
#include "config.h"
#include "bgBottom.h"
#include "bgTop.h"
#include "bgMenu-Green.h"
#include "bgMenu-White.h"
#include "Emulator.h"

View File

@ -26,6 +26,7 @@
#include "manual.h"
#include "bgBottom.h"
#include "bgTop.h"
#include "bgTop2K.h"
#include "bgMenu-Green.h"
#include "bgMenu-White.h"
#include "Emulator.h"
@ -1240,9 +1241,15 @@ void dsShowScreenMain(bool bFull, bool bPlayJingle)
bg1b = bgInitSub(1, BgType_Text8bpp, BgSize_T_256x256, 30,0);
bgSetPriority(bg0b,1);bgSetPriority(bg1b,0);
#ifdef GRAM_2K
decompress(bgTop2KTiles, bgGetGfxPtr(bg0), LZ77Vram);
decompress(bgTop2KMap, (void*) bgGetMapPtr(bg0), LZ77Vram);
dmaCopy((void *) bgTop2KPal,(u16*) BG_PALETTE,256*2);
#else
decompress(bgTopTiles, bgGetGfxPtr(bg0), LZ77Vram);
decompress(bgTopMap, (void*) bgGetMapPtr(bg0), LZ77Vram);
dmaCopy((void *) bgTopPal,(u16*) BG_PALETTE,256*2);
#endif
if (bPlayJingle)
{

Binary file not shown.