diff --git a/Makefile b/Makefile index b02305e..a9b47b9 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ include $(DEVKITARM)/ds_rules export TARGET := NINTV-DS export TOPDIR := $(CURDIR) -export VERSION := 3.8b +export VERSION := 3.8c ICON := -b $(CURDIR)/logo.bmp "NINTV-DS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/NINTV-DS" diff --git a/NINTV-DS.nds b/NINTV-DS.nds index 4b857ff..52af1dc 100644 Binary files a/NINTV-DS.nds and b/NINTV-DS.nds differ diff --git a/README.md b/README.md index 3ef7005..2700caf 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Credits : BLISS - Intellivision Emulator. Originally developed by Kyle Davis. Contributions by Jesse Litton, Mike Dunston, Joseph Zbiciak. Most of the cheats are provided by the excellent work found at: http://www.midnightblueinternational.com/romhacks.php Thanks to Michael Hayes for allowing the inclusion into NINTV-DS +And special thanks to Joseph Zbiciak (jzintv fame) for detailed descriptions of all the ins and outs of Intellivision hardware so that better emulation is possible! -------------------------------------------------------------------------------- diff --git a/arm7/source/emusoundfifo.c b/arm7/source/emusoundfifo.c index 1216fe5..2ed9e55 100644 --- a/arm7/source/emusoundfifo.c +++ b/arm7/source/emusoundfifo.c @@ -22,11 +22,11 @@ typedef enum { //--------------------------------------------------------------------------------- void soundEmuDataHandler(int bytes, void *user_data) { - int channel = -1; + int channel = -1; - FifoMessage msg; + FifoMessage msg; - fifoGetDatamsg(FIFO_USER_01, bytes, (u8*)&msg); + fifoGetDatamsg(FIFO_USER_01, bytes, (u8*)&msg); switch (msg.type) { case EMUARM7_PLAY_SND: @@ -48,48 +48,48 @@ void soundEmuDataHandler(int bytes, void *user_data) //--------------------------------------------------------------------------------- void soundEmuCommandHandler(u32 command, void* userdata) { - int cmd = (command ) & 0x00F00000; - int data = command & 0xFFFF; - int channel = (command >> 16) & 0xF; - - switch(cmd) + int cmd = (command ) & 0x00F00000; + int data = command & 0xFFFF; + int channel = (command >> 16) & 0xF; + + switch(cmd) { - case SOUND_SET_VOLUME: - SCHANNEL_CR(channel) &= ~0xFF; - SCHANNEL_CR(channel) |= data; - break; + case SOUND_SET_VOLUME: + SCHANNEL_CR(channel) &= ~0xFF; + SCHANNEL_CR(channel) |= data; + break; - case SOUND_SET_PAN: - SCHANNEL_CR(channel) &= ~SOUND_PAN(0xFF); - SCHANNEL_CR(channel) |= SOUND_PAN(data); - break; + case SOUND_SET_PAN: + SCHANNEL_CR(channel) &= ~SOUND_PAN(0xFF); + SCHANNEL_CR(channel) |= SOUND_PAN(data); + break; - case SOUND_SET_FREQ: - SCHANNEL_TIMER(channel) = SOUND_FREQ(data); - break; + case SOUND_SET_FREQ: + SCHANNEL_TIMER(channel) = SOUND_FREQ(data); + break; - case SOUND_SET_WAVEDUTY: - SCHANNEL_CR(channel) &= ~(7 << 24); - SCHANNEL_CR(channel) |= (data) << 24; - break; + case SOUND_SET_WAVEDUTY: + SCHANNEL_CR(channel) &= ~(7 << 24); + SCHANNEL_CR(channel) |= (data) << 24; + break; - case SOUND_KILL: - case SOUND_PAUSE: - SCHANNEL_CR(channel) &= ~SCHANNEL_ENABLE; - break; + case SOUND_KILL: + case SOUND_PAUSE: + SCHANNEL_CR(channel) &= ~SCHANNEL_ENABLE; + break; - case SOUND_RESUME: - SCHANNEL_CR(channel) |= SCHANNEL_ENABLE; - break; + case SOUND_RESUME: + SCHANNEL_CR(channel) |= SCHANNEL_ENABLE; + break; - default: break; - } + default: break; + } } //--------------------------------------------------------------------------------- void installSoundEmuFIFO(void) { - fifoSetDatamsgHandler(FIFO_USER_01, soundEmuDataHandler, 0); - fifoSetValue32Handler(FIFO_USER_01, soundEmuCommandHandler, 0); + fifoSetDatamsgHandler(FIFO_USER_01, soundEmuDataHandler, 0); + fifoSetValue32Handler(FIFO_USER_01, soundEmuCommandHandler, 0); } diff --git a/arm7/source/main.c b/arm7/source/main.c index dcbc6e1..121753f 100644 --- a/arm7/source/main.c +++ b/arm7/source/main.c @@ -11,31 +11,31 @@ /*--------------------------------------------------------------------------------- - default ARM7 core + default ARM7 core - Copyright (C) 2005 - 2010 - Michael Noland (joat) - Jason Rogers (dovoto) - Dave Murphy (WinterMute) + Copyright (C) 2005 - 2010 + Michael Noland (joat) + Jason Rogers (dovoto) + Dave Murphy (WinterMute) - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any - damages arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any + damages arising from the use of this software. - Permission is granted to anyone to use this software for any - purpose, including commercial applications, and to alter it and - redistribute it freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any + purpose, including commercial applications, and to alter it and + redistribute it freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you - must not claim that you wrote the original software. If you use - this software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. + 2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. - 3. This notice may not be removed or altered from any source - distribution. + 3. This notice may not be removed or altered from any source + distribution. ---------------------------------------------------------------------------------*/ #include @@ -44,17 +44,18 @@ extern void installSoundEmuFIFO(void); + //--------------------------------------------------------------------------------- void VblankHandler(void) { //--------------------------------------------------------------------------------- - Wifi_Update(); + Wifi_Update(); } //--------------------------------------------------------------------------------- void VcountHandler() { //--------------------------------------------------------------------------------- - inputGetAndSend(); + inputGetAndSend(); } volatile bool exitflag = false; @@ -62,45 +63,45 @@ volatile bool exitflag = false; //--------------------------------------------------------------------------------- void powerButtonCB() { //--------------------------------------------------------------------------------- - exitflag = true; + exitflag = true; } //--------------------------------------------------------------------------------- int main() { //--------------------------------------------------------------------------------- - readUserSettings(); + readUserSettings(); - irqInit(); - // Start the RTC tracking IRQ - initClockIRQ(); - touchInit(); - fifoInit(); + irqInit(); + // Start the RTC tracking IRQ + initClockIRQ(); + touchInit(); + fifoInit(); - //mmInstall(FIFO_MAXMOD); + //mmInstall(FIFO_MAXMOD); - SetYtrigger(80); + SetYtrigger(80); - installWifiFIFO(); - installSoundFIFO(); + installWifiFIFO(); + installSoundFIFO(); - installSystemFIFO(); + installSystemFIFO(); installSoundEmuFIFO(); - irqSet(IRQ_VCOUNT, VcountHandler); - irqSet(IRQ_VBLANK, VblankHandler); + irqSet(IRQ_VCOUNT, VcountHandler); + irqSet(IRQ_VBLANK, VblankHandler); - irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK); - - setPowerButtonCB(powerButtonCB); - - // Keep the ARM7 mostly idle - while (!exitflag) { - if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) { - exitflag = true; - } + irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK); - swiWaitForVBlank(); - } - return 0; + setPowerButtonCB(powerButtonCB); + + // Keep the ARM7 mostly idle + while (!exitflag) { + if ( 0 == (REG_KEYINPUT & (KEY_SELECT | KEY_START | KEY_L | KEY_R))) { + exitflag = true; + } + + swiWaitForVBlank(); + } + return 0; } diff --git a/arm9/Makefile b/arm9/Makefile index 3cc5f22..f7da158 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -14,11 +14,11 @@ include $(DEVKITARM)/ds_rules # DATA is a list of directories containing binary files # all directories are relative to this makefile #--------------------------------------------------------------------------------- -BUILD := build -SOURCES := source/emucore source/common source -INCLUDES := source/emucore source/common include -DATA := data -GRAPHICS := gfx +BUILD := build +SOURCES := source/emucore source/common source +INCLUDES := source/emucore source/common include +DATA := data +GRAPHICS := gfx #--------------------------------------------------------------------------------- # options for code generation @@ -26,8 +26,8 @@ GRAPHICS := gfx #ARCH := -mthumb -mthumb-interwork ARCH := -#CFLAGS := -g -Wall -O2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math $(ARCH) -CFLAGS := -Wno-address-of-packed-member -Wno-multichar -O3 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math $(ARCH) +#CFLAGS := -Wno-address-of-packed-member -Wno-multichar -O3 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math $(ARCH) +CFLAGS := -Ofast -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math $(ARCH) -falign-functions=16 -frename-registers CFLAGS += $(INCLUDE) -DARM9 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -Wno-conversion-null diff --git a/arm9/source/debugger.cpp b/arm9/source/debugger.cpp index 651bb24..3b3addb 100644 --- a/arm9/source/debugger.cpp +++ b/arm9/source/debugger.cpp @@ -48,6 +48,8 @@ extern struct Overlay_t defaultOverlay[OVL_MAX]; extern Emulator *currentEmu; AY38900 *debug_stic = NULL; +AY38914 *debug_psg = NULL; +AY38914 *debug_psg2 = NULL; void display_debug(void); @@ -95,11 +97,6 @@ extern UINT8 D; extern UINT16 op; extern UINT8 oneSecTick; -#define DBG_PRESS_PLAY 0 -#define DBG_PRESS_STOP 1 -#define DBG_PRESS_STEP 2 -#define DBG_PRESS_FRAME 3 -#define DBG_PRESS_NONE 255 #define DBG_MODE_PLAY 0 #define DBG_MODE_STOP 1 @@ -115,6 +112,7 @@ UINT8 debug_mode = DBG_MODE_PLAY; UINT8 debug_show = DBG_SHOW_CPU; +UINT8 debug_show_cpu = 0; UINT8 debug_show_ram = 0; UINT8 debug_show_stic = 0; UINT8 debug_show_psg = 0; @@ -3196,8 +3194,8 @@ void show_debug_overlay(void) dmaFillWords(dmaVal | (dmaVal<<16),(void*) bgGetMapPtr(bg1b),32*24*2); REG_BLDCNT=0; REG_BLDCNT_SUB=0; REG_BLDY=0; REG_BLDY_SUB=0; - - swiWaitForVBlank(); + + swiWaitForVBlank(); } @@ -3216,14 +3214,17 @@ void debugger_wait_for_input(void) while (!bDone) { - while ((keysCurrent() & KEY_TOUCH) == 0) + while ((keysCurrent() & KEY_TOUCH) == 0) // Wait for press { - asm("nop"); + WAITVBL; } touchRead(&touch); + while (keysCurrent() & KEY_TOUCH) // Wait for release + { + WAITVBL; + } UINT8 pressed = debugger_input(touch.px, touch.py); - - if ((pressed != DBG_PRESS_NONE) && (pressed != DBG_PRESS_STOP)) + if ((pressed != DBG_PRESS_NONE) && (pressed != DBG_PRESS_META) && (pressed != DBG_PRESS_STOP)) { bDone=true; } @@ -3231,11 +3232,11 @@ void debugger_wait_for_input(void) { display_debug(); } - WAITVBL;WAITVBL;WAITVBL; + WAITVBL;WAITVBL;WAITVBL; } } -UINT8 debugger_input(int tx, int ty) +UINT8 debugger_input(UINT16 tx, UINT16 ty) { UINT8 pressed = DBG_PRESS_NONE; @@ -3247,7 +3248,10 @@ UINT8 debugger_input(int tx, int ty) if ((tx > 163) && (tx < 198) && (ty > 160) && (ty < 180)) { debug_clear_scr(); + if (debug_show == DBG_SHOW_CPU) debug_show_cpu = (debug_show_cpu+1) % 2; + else debug_show_cpu = 0; debug_show = DBG_SHOW_CPU; + pressed = DBG_PRESS_META; } if ((tx > 198) && (tx < 236) && (ty > 160) && (ty < 180)) { @@ -3255,13 +3259,15 @@ UINT8 debugger_input(int tx, int ty) if (debug_show == DBG_SHOW_RAM) debug_show_ram = (debug_show_ram+1) % 3; else debug_show_ram = 0; debug_show = DBG_SHOW_RAM; + pressed = DBG_PRESS_META; } if ((tx > 163) && (tx < 198) && (ty > 180)) { debug_clear_scr(); - if (debug_show == DBG_SHOW_PSG) debug_show_psg = (debug_show_psg+1) % 2; + if (debug_show == DBG_SHOW_PSG) debug_show_psg = (debug_show_psg+1) % 3; else debug_show_psg = 0; debug_show = DBG_SHOW_PSG; + pressed = DBG_PRESS_META; } if ((tx > 198) && (tx < 236) && (ty > 180)) { @@ -3269,6 +3275,7 @@ UINT8 debugger_input(int tx, int ty) if (debug_show == DBG_SHOW_STIC) debug_show_stic = (debug_show_stic+1) % 8; else debug_show_stic = 0; debug_show = DBG_SHOW_STIC; + pressed = DBG_PRESS_META; } return pressed; } @@ -3280,39 +3287,57 @@ void display_debug(void) if (debug_show == DBG_SHOW_CPU) { - for (int i=0; i<8; i++) + switch (debug_show_cpu) { - sprintf(dbg, "R%d: %-5d %04X", i, r[i], r[i]); - dsPrintValue(0, idx++, 0, dbg); - } - idx++; - sprintf(dbg, " S: %02X", S); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, " Z: %02X", Z); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, " O: %02X", O); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, " C: %02X", C); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, " I: %02X", I); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, " D: %02X", D); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "EB: %04X", PEEK_FAST(0x50eb)); dsPrintValue(0, idx++, 0, dbg); - - idx++; - sprintf(dbg, "OP: %03X [%-15s]", op, dbg_opcode(op)); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "Total Frames: %-9u ", global_frames); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "Total OpCode: %-9u ", debug_opcodes); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "Memory Used: %-9d ", getMemUsed()); dsPrintValue(0, idx++, 0, dbg); + case 0: + for (int i=0; i<8; i++) + { + sprintf(dbg, "R%d: %-5d %04X", i, r[i], r[i]); + dsPrintValue(0, idx++, 0, dbg); + } + idx++; + sprintf(dbg, " S: %02X", S); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, " Z: %02X", Z); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, " O: %02X", O); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, " C: %02X", C); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, " I: %02X", I); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, " D: %02X", D); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "EB: %04X", PEEK_FAST(0x50eb)); dsPrintValue(0, idx++, 0, dbg); - idx=0; - for (UINT16 addr = r[7]-3; addr <= r[7]+4; addr++) - { - sprintf(dbg, "A=%04X : D=%04X", addr, PEEK_FAST(addr)); - dsPrintValue(16, idx++, (addr == r[7] ? 1:0), dbg); + idx++; + sprintf(dbg, "OP: %03X [%-15s]", op, dbg_opcode(op)); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "Total Frames: %-9u ", global_frames); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "Total OpCode: %-9u ", debug_opcodes); dsPrintValue(0, idx++, 0, dbg); + + idx=0; + for (UINT16 addr = r[7]-3; addr <= r[7]+4; addr++) + { + sprintf(dbg, "A=%04X : D=%04X", addr, PEEK_FAST(addr)); + dsPrintValue(16, idx++, (addr == r[7] ? 1:0), dbg); + } + idx++; + for (int i=0; i<6; i++) + { + sprintf(dbg, "D%d=%-09d %08X", i, debug[i], debug[i]); + dsPrintValue(10, idx++, 0, dbg); + } + break; + + case 1: + extern UINT8 gBankerIsMappedHere[16][16]; + extern UINT16 gLastBankers[16]; + dsPrintValue(13, idx++, 0, (char*)"BANKING "); + idx++; + for (int i=0; i<16; i++) + { + sprintf(dbg, "%X000: %d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d %X", i, gBankerIsMappedHere[i][0], gBankerIsMappedHere[i][1], gBankerIsMappedHere[i][2], gBankerIsMappedHere[i][3], + gBankerIsMappedHere[i][4], gBankerIsMappedHere[i][5], gBankerIsMappedHere[i][6], gBankerIsMappedHere[i][7], gBankerIsMappedHere[i][8], gBankerIsMappedHere[i][9], + gBankerIsMappedHere[i][10], gBankerIsMappedHere[i][11], gBankerIsMappedHere[i][12], gBankerIsMappedHere[i][13], gBankerIsMappedHere[i][14], gBankerIsMappedHere[i][15], (gLastBankers[i]&0xF)); + dsPrintValue(1, idx++, 0, dbg); + + } + break; } - idx++; - for (int i=0; i<6; i++) - { - sprintf(dbg, "D%d=%-09d %08X", i, debug[i], debug[i]); - dsPrintValue(10, idx++, 0, dbg); - } - } if (debug_show == DBG_SHOW_RAM) { @@ -3351,70 +3376,104 @@ void display_debug(void) if (debug_show == DBG_SHOW_PSG) { idx=0; - extern struct Channel_t channel0; - extern struct Channel_t channel1; - extern struct Channel_t channel2; - + switch (debug_show_psg) { case 0: -#if 0 sprintf(dbg, " CHAN1 CHAN2 CHAN3"); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "Period: %-5d %-5d %-5d", channel0.period, channel1.period, channel2.period); + sprintf(dbg, "Period: %-5d %-5d %-5d", debug_psg->channel0.period, debug_psg->channel1.period, debug_psg->channel2.period); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "PerVal: %-5d %-5d %-5d", channel0.periodValue, channel1.periodValue, channel2.periodValue); + sprintf(dbg, "PerVal: %-5d %-5d %-5d", debug_psg->channel0.periodValue, debug_psg->channel1.periodValue, debug_psg->channel2.periodValue); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "Volume: %-5d %-5d %-5d", channel0.volume, channel1.volume, channel2.volume); + sprintf(dbg, "Volume: %-5d %-5d %-5d", debug_psg->channel0.volume, debug_psg->channel1.volume, debug_psg->channel2.volume); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "ToneCt: %-5d %-5d %-5d", channel0.toneCounter, channel1.toneCounter, channel2.toneCounter); + sprintf(dbg, "ToneCt: %-5d %-5d %-5d", debug_psg->channel0.toneCounter, debug_psg->channel1.toneCounter, debug_psg->channel2.toneCounter); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "Tone: %-5d %-5d %-5d", channel0.tone, channel1.tone, channel2.tone); + sprintf(dbg, "Tone: %-5d %-5d %-5d", debug_psg->channel0.tone, debug_psg->channel1.tone, debug_psg->channel2.tone); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "Envlop: %-5d %-5d %-5d", channel0.envelope, channel1.envelope, channel2.envelope); + sprintf(dbg, "Envlop: %-5d %-5d %-5d", debug_psg->channel0.envelope, debug_psg->channel1.envelope, debug_psg->channel2.envelope); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "TonDis: %-5d %-5d %-5d", channel0.toneDisabled, channel1.toneDisabled, channel2.toneDisabled); + sprintf(dbg, "TonDis: %-5d %-5d %-5d", debug_psg->channel0.toneDisabled, debug_psg->channel1.toneDisabled, debug_psg->channel2.toneDisabled); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "NoiDis: %-5d %-5d %-5d", channel0.noiseDisabled, channel1.noiseDisabled, channel2.noiseDisabled); + sprintf(dbg, "NoiDis: %-5d %-5d %-5d", debug_psg->channel0.noiseDisabled, debug_psg->channel1.noiseDisabled, debug_psg->channel2.noiseDisabled); dsPrintValue(0, idx++, 0, dbg); idx++; sprintf(dbg, "clockDivisor: %-9d", clockDivisor); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "clocksPerSample: %-9d", clocksPerSample); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "envelopeIdle: %-9d", envelopeIdle); + sprintf(dbg, "envelopeIdle: %-9d", debug_psg->envelopeIdle); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "envelopePeriod: %-9d", envelopePeriod); + sprintf(dbg, "envelopePeriod: %-9d", debug_psg->envelopePeriod); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "envelopePValue: %-9d", envelopePeriodValue); + sprintf(dbg, "envelopePValue: %-9d", debug_psg->envelopePeriodValue); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "noiseIdle: %-9d", noiseIdle); + sprintf(dbg, "noiseIdle: %-9d", debug_psg->noiseIdle); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "noisePeriod: %-9d", noisePeriod); + sprintf(dbg, "noisePeriod: %-9d", debug_psg->noisePeriod); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "noisePeriodValue: %-9d", noisePeriodValue); + sprintf(dbg, "noisePeriodValue: %-9d", debug_psg->noisePeriodValue); dsPrintValue(0, idx++, 0, dbg); -#endif break; case 1: + sprintf(dbg, " CHAN4 CHAN5 CHAN6"); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "Period: %-5d %-5d %-5d", debug_psg2->channel0.period, debug_psg2->channel1.period, debug_psg2->channel2.period); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "PerVal: %-5d %-5d %-5d", debug_psg2->channel0.periodValue, debug_psg2->channel1.periodValue, debug_psg2->channel2.periodValue); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "Volume: %-5d %-5d %-5d", debug_psg2->channel0.volume, debug_psg2->channel1.volume, debug_psg2->channel2.volume); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "ToneCt: %-5d %-5d %-5d", debug_psg2->channel0.toneCounter, debug_psg2->channel1.toneCounter, debug_psg2->channel2.toneCounter); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "Tone: %-5d %-5d %-5d", debug_psg2->channel0.tone, debug_psg2->channel1.tone, debug_psg2->channel2.tone); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "Envlop: %-5d %-5d %-5d", debug_psg2->channel0.envelope, debug_psg2->channel1.envelope, debug_psg2->channel2.envelope); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "TonDis: %-5d %-5d %-5d", debug_psg2->channel0.toneDisabled, debug_psg2->channel1.toneDisabled, debug_psg2->channel2.toneDisabled); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "NoiDis: %-5d %-5d %-5d", debug_psg2->channel0.noiseDisabled, debug_psg2->channel1.noiseDisabled, debug_psg2->channel2.noiseDisabled); + dsPrintValue(0, idx++, 0, dbg); + idx++; + sprintf(dbg, "clockDivisor: %-9d", clockDivisor); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "clocksPerSample: %-9d", clocksPerSample); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "envelopeIdle: %-9d", debug_psg2->envelopeIdle); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "envelopePeriod: %-9d", debug_psg2->envelopePeriod); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "envelopePValue: %-9d", debug_psg2->envelopePeriodValue); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "noiseIdle: %-9d", debug_psg2->noiseIdle); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "noisePeriod: %-9d", debug_psg2->noisePeriod); + dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "noisePeriodValue: %-9d", debug_psg2->noisePeriodValue); + dsPrintValue(0, idx++, 0, dbg); + break; + + + case 2: sprintf(dbg, "AUDIO MIXER BUFFER"); dsPrintValue(0, idx++, 0, dbg); idx++; sprintf(dbg, "curSampIdx8 %-4d", currentSampleIdx8); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "comClksPerTik %-9d", commonClocksPerTick); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "sampleBuf[0] %-17lld", (long long)sampleBuffer[0]); + sprintf(dbg, "sampleBuf[0] %-17ld", (long)sampleBuffer[0]); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "sampleBuf[1] %-17lld", (long long)sampleBuffer[1]); + sprintf(dbg, "sampleBuf[1] %-17ld", (long)sampleBuffer[1]); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "comClkCntr[0] %-17lld", (long long)commonClockCounter[0]); + sprintf(dbg, "comClkCntr[0] %-17ld", (long)commonClockCounter[0]); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "comClkCntr[1] %-17lld", (long long)commonClockCounter[1]); + sprintf(dbg, "comClkCntr[1] %-17ld", (long)commonClockCounter[1]); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "comClkPerS[0] %-17lld", (long long)commonClocksPerSample[0]); + sprintf(dbg, "comClkPerS[0] %-17ld", (long)commonClocksPerSample[0]); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "comClkPerS[1] %-17lld", (long long)commonClocksPerSample[1]); + sprintf(dbg, "comClkPerS[1] %-17ld", (long)commonClocksPerSample[1]); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "prevSample[] %04X %04X", previousSample[0], previousSample[1]); dsPrintValue(0, idx++, 0, dbg); diff --git a/arm9/source/debugger.h b/arm9/source/debugger.h index 77dcec4..eed1c1d 100644 --- a/arm9/source/debugger.h +++ b/arm9/source/debugger.h @@ -17,16 +17,26 @@ #include #include "types.h" #include "AY38900.h" +#include "AY38914.h" + +#define DBG_PRESS_PLAY 0 +#define DBG_PRESS_STOP 1 +#define DBG_PRESS_STEP 2 +#define DBG_PRESS_FRAME 3 +#define DBG_PRESS_META 254 +#define DBG_PRESS_NONE 255 extern UINT32 debug_frames; extern UINT32 debug_opcodes; extern AY38900 *debug_stic; +extern AY38914 *debug_psg; +extern AY38914 *debug_psg2; extern INT32 debug[]; extern void show_debug_overlay(void); extern void debugger(void); -extern UINT8 debugger_input(int tx, int ty); +extern UINT8 debugger_input(UINT16 tx, UINT16 ty); extern int getMemUsed(void); #endif diff --git a/arm9/source/ds_tools.cpp b/arm9/source/ds_tools.cpp index d8d518b..cfaccc1 100644 --- a/arm9/source/ds_tools.cpp +++ b/arm9/source/ds_tools.cpp @@ -319,7 +319,7 @@ void dsShowEmuInfo(void) if (currentRip != NULL) { - sprintf(dbg, "CPU Mode: %s", isDSiMode() ? "DSI 134MHz / 16MB":"DS 67MHz / 4 MB"); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "CPU Mode: %s", isDSiMode() ? "DSI 134MHz 16MB":"DS 67MHz 4 MB"); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "Binary Size: %-9u ", currentRip->GetSize()); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "Binary CRC: %08X ", currentRip->GetCRC()); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "Intellivoice: %s ", (bUseIVoice ? "YES":"NO")); dsPrintValue(0, idx++, 0, dbg); @@ -330,11 +330,14 @@ void dsShowEmuInfo(void) sprintf(dbg, "RAM Indexes: %d / %d ", fast_ram16_idx, slow_ram16_idx); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "MEMS MAPPED: %-9d ", currentEmu->memoryBus.getMemCount());dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "RIP ROM Count: %-9d ", currentRip->GetROMCount()); dsPrintValue(0, idx++, 0, dbg); - sprintf(dbg, "RIP RAM Count: %-9d ", currentRip->GetRAMCount()); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "RIP RAM Count: %-9d ", currentRip->GetRAMCount()); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "Compat Tags: %02X %02X %02X %02X %02X", tag_compatibility[0], + tag_compatibility[1], tag_compatibility[2], tag_compatibility[3], + tag_compatibility[4]); dsPrintValue(0, idx++, 0, dbg); } else { - sprintf(dbg, "CPU Mode: %s", isDSiMode() ? "DSI 134MHz / 16MB":"DS 67MHz / 4 MB"); dsPrintValue(0, idx++, 0, dbg); + sprintf(dbg, "CPU Mode: %s", isDSiMode() ? "DSI 134MHz 16MB":"DS 67MHz 4 MB"); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "Memory Used: %-9d ", getMemUsed()); dsPrintValue(0, idx++, 0, dbg); sprintf(dbg, "NO GAME IS LOADED!"); dsPrintValue(0, idx++, 0, dbg); } @@ -946,9 +949,15 @@ ITCM_CODE void pollInputs(void) { touchPosition touch; touchRead(&touch); - #ifdef DEBUG_ENABLE - debugger_input(touch.px, touch.py); + if (debugger_input(touch.px, touch.py) == DBG_PRESS_META) + { + while (keysCurrent() & KEY_TOUCH) // Wait for release + { + WAITVBL; + } + WAITVBL; + } #endif // ----------------------------------------------------------- // Did we map any hotspots on the overlay to disc directions? @@ -1367,10 +1376,16 @@ ITCM_CODE void Run(char *initial_file) // If we've been asked to put out the debug info at the top of the screen... mostly for developer use if (myGlobalConfig.show_fps == 2) { - //sprintf(tmp,"%-6d %-6d %-5d %-5d", debug[0], debug[1], debug[2], debug[3]); - sprintf(tmp,"%04X %04X %04X %04X %02X %02X", debug[0], debug[1], debug[2], debug[3], debug[4], debug[5]); + sprintf(tmp,"%-6d %-6d %-5d %-5d", debug[0], debug[1], debug[2], debug[3]); + //sprintf(tmp,"%04X %04X %04X %04X %02X %02X", debug[0], debug[1], debug[2], debug[3], debug[4], debug[5]); dsPrintValue(6,0,0,tmp); } + + // If we are using the JLP, we call into the 1 second tick function in case there is a dirty flash that needs writing... + if (bUseJLP) + { + currentRip->JLP16Bit->tick_one_second(); + } } #ifdef DEBUG_ENABLE diff --git a/arm9/source/emucore/AY38914_Channel.h b/arm9/source/emucore/AY38914_Channel.h index 3c5971d..350bf52 100644 --- a/arm9/source/emucore/AY38914_Channel.h +++ b/arm9/source/emucore/AY38914_Channel.h @@ -27,8 +27,4 @@ struct Channel_t UINT8 isDirty; }; -extern struct Channel_t channel0; -extern struct Channel_t channel1; -extern struct Channel_t channel2; - #endif diff --git a/arm9/source/emucore/ECS.cpp b/arm9/source/emucore/ECS.cpp index e0ee2ba..4c2ff04 100644 --- a/arm9/source/emucore/ECS.cpp +++ b/arm9/source/emucore/ECS.cpp @@ -10,6 +10,7 @@ // ===================================================================================== #include "ECS.h" +#include "../debugger.h" extern UINT8 ecs_ram[]; @@ -39,10 +40,14 @@ ECS::ECS() AddRAM(&ecsRAM); +#ifdef DEBUG_ENABLE + debug_psg2 = &psg2; +#endif + AddProcessor(&psg2); AddAudioProducer(&psg2); AddRAM(&psg2.registers); - + AddInputConsumer(&keyboard); } diff --git a/arm9/source/emucore/Intellivision.cpp b/arm9/source/emucore/Intellivision.cpp index bac0722..0ecab4a 100644 --- a/arm9/source/emucore/Intellivision.cpp +++ b/arm9/source/emucore/Intellivision.cpp @@ -75,6 +75,7 @@ Intellivision::Intellivision() #ifdef DEBUG_ENABLE debug_stic = &stic; + debug_psg = &psg; #endif //add the PSG diff --git a/arm9/source/emucore/JLP.cpp b/arm9/source/emucore/JLP.cpp index 3963248..f93be79 100644 --- a/arm9/source/emucore/JLP.cpp +++ b/arm9/source/emucore/JLP.cpp @@ -18,6 +18,7 @@ #include "RAM.h" #include "Rip.h" #include "../config.h" +#include "../ds_tools.h" extern Rip *currentRip; @@ -30,7 +31,7 @@ void JLP::reset() enabled = TRUE; for (UINT16 i = 0; i < JLP_RAM_SIZE; i++) jlp_ram[i] = 0xFFFF; - jlp_ram[JLP_RAM_SIZE-1] = 0; + jlp_ram[JLP_RAM_SIZE-1] = 0; /* The last byte of jlp RAM reads back as 0 */ jlp_ram[0x23] = 0; /* First valid flash row number */ jlp_ram[0x24] = NUM_JLP_ROWS; /* Last valid flash row number */ @@ -38,7 +39,21 @@ void JLP::reset() jlp_ram[0x2E] = 0; /* Command regs read as 0 */ jlp_ram[0x2F] = 0; /* Command regs read as 0 */ - flash_read = 1; // Force flash to read... + flash_read = 1; // Force flash to read... + flash_write_time = 0; // And reset the time to write... +} + +// If the JLP flash needs to be written, we write it to the backing file. We do it this way so that quick-succession writes +// to the flash do not force a write to the backing file which is slow and wasteful... so we have a 2 second backing timer. +void JLP::tick_one_second(void) +{ + if (flash_write_time > 0) + { + if (--flash_write_time == 0) + { + WriteFlashFile(); + } + } } UINT16 JLP::peek(UINT16 location) @@ -113,6 +128,7 @@ void JLP::WriteFlashFile(void) { FILE *fp; + dsPrintValue(23,0,0, (char*)"JLP FLASH"); GetFlashFilename(); fp = fopen(flash_filename, "wb"); if (fp != NULL) @@ -120,12 +136,17 @@ void JLP::WriteFlashFile(void) fwrite(jlp_flash, 1, JLP_FLASH_SIZE, fp); fclose(fp); } + dsPrintValue(23,0,0,(char*)" "); } +void JLP::ScheduleWriteFlashFile(void) +{ + flash_write_time = 2; +} void JLP::RamToFlash(void) { - UINT32 addr = jlp_ram[(0x8025&readAddressMask) - this->location] - 0x8000; + UINT32 addr = jlp_ram[(0x8025&readAddressMask) - this->location] - JLP_RAM_ADDRESS; UINT32 row = (jlp_ram[(0x8026&readAddressMask) - this->location] - jlp_ram[(0x8023&readAddressMask) - this->location]) * 192; int i, a; @@ -146,12 +167,12 @@ void JLP::RamToFlash(void) jlp_flash[row + i + 0] = jlp_ram[addr + a] & 0xFF; jlp_flash[row + i + 1] = jlp_ram[addr + a] >> 8; } - WriteFlashFile(); + ScheduleWriteFlashFile(); } void JLP::FlashToRam(void) { - UINT32 addr = jlp_ram[(0x8025&readAddressMask) - this->location] - 0x8000; + UINT32 addr = jlp_ram[(0x8025&readAddressMask) - this->location] - JLP_RAM_ADDRESS; UINT32 row = (jlp_ram[(0x8026&readAddressMask) - this->location] - jlp_ram[(0x8023&readAddressMask) - this->location]) * 192; int i, a; @@ -166,8 +187,7 @@ void JLP::FlashToRam(void) UINT16 lo = jlp_flash[row + i + 0]; UINT16 hi = jlp_flash[row + i + 1]; jlp_ram[addr + a] = lo | (hi << 8); - } - + } } void JLP::EraseSector(void) @@ -176,7 +196,7 @@ void JLP::EraseSector(void) if (jlp_ram[(0x8026&readAddressMask) - this->location] > NUM_JLP_ROWS) return; if (flash_read) ReadFlashFile(); memset((void *)&jlp_flash[row], 0xFF, 192 * 8); - WriteFlashFile(); + ScheduleWriteFlashFile(); } diff --git a/arm9/source/emucore/JLP.h b/arm9/source/emucore/JLP.h index 06511ef..620111a 100644 --- a/arm9/source/emucore/JLP.h +++ b/arm9/source/emucore/JLP.h @@ -34,6 +34,7 @@ class JLP : public RAM void reset(); UINT16 peek(UINT16 location); void poke(UINT16 location, UINT16 value); + void tick_one_second(void); void getState(JLPState *state); void setState(JLPState *state); @@ -46,8 +47,10 @@ class JLP : public RAM void EraseSector(void); void ReadFlashFile(void); void WriteFlashFile(void); + void ScheduleWriteFlashFile(void); void GetFlashFilename(void); UINT8 flash_read; + UINT8 flash_write_time; }; #endif diff --git a/arm9/source/emucore/Memory.h b/arm9/source/emucore/Memory.h index f842cbc..2d056c9 100644 --- a/arm9/source/emucore/Memory.h +++ b/arm9/source/emucore/Memory.h @@ -19,7 +19,6 @@ #define MAX_COMPONENTS 4 #define MAX_ROMS 128 -extern UINT16 MAX_OVERLAPPED_MEMORIES; extern UINT32 MAX_ROM_FILE_SIZE; class Memory diff --git a/arm9/source/emucore/MemoryBus.cpp b/arm9/source/emucore/MemoryBus.cpp index d332896..0a38988 100644 --- a/arm9/source/emucore/MemoryBus.cpp +++ b/arm9/source/emucore/MemoryBus.cpp @@ -14,7 +14,8 @@ #include "MemoryBus.h" #include "../ds_tools.h" -UINT16 MAX_OVERLAPPED_MEMORIES = 3; +UINT16 MAX_READ_OVERLAPPED_MEMORIES = 2; +UINT16 MAX_WRITE_OVERLAPPED_MEMORIES = 3; // ---------------------------------------------------------------------------------------------- // We use this class and single object to fill all unused memory locations in the memory map. @@ -60,11 +61,13 @@ MemoryBus::MemoryBus() // ------------------------------------------------------------------------------------- if (isDSiMode()) { - MAX_OVERLAPPED_MEMORIES = 16; // This will handle massive page-flip (banked) games + 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 splaces in ROM } else { - MAX_OVERLAPPED_MEMORIES = 3; // Good enough for almost all games + MAX_READ_OVERLAPPED_MEMORIES = 2; // Good enough for almost all games except very large page-flipping games + MAX_WRITE_OVERLAPPED_MEMORIES = 3; // Need one extra here to handle the GRAM mirrors up in odd splaces in ROM } UINT32 size = 1 << (sizeof(UINT16) << 3); @@ -78,12 +81,12 @@ MemoryBus::MemoryBus() // On the DS with 3 overlapped memories (enough for most games), this is still 1.5MB of memory (out of the 3.5MB available) // On the DSi with a full 16 overlapped memories (enough for any game), this is a whopping 8MB (out of the 15.5MB available) // --------------------------------------------------------------------------------------------------------------------------- - overlappedMemoryPool = new UINT32[size*MAX_OVERLAPPED_MEMORIES*2]; + overlappedMemoryPool = new UINT32[size*(MAX_READ_OVERLAPPED_MEMORIES+MAX_WRITE_OVERLAPPED_MEMORIES)]; for (i = 0; i < size; i++) { - writeableMemorySpace[i] = (Memory **)overlappedMemoryPool;//new Memory*[MAX_OVERLAPPED_MEMORIES]; - for (int j=0; j= MAX_READ_OVERLAPPED_MEMORIES) + { + FatalError("ERROR MAX READABLE MEM OVERLAP"); + return; + } readableMemorySpace[k][memCount] = m; readableMemoryCounts[k]++; } @@ -184,6 +192,11 @@ void MemoryBus::addMemory(Memory* m) for (UINT32 k = nextAddress; k <= nextEnd; k++) { UINT16 memCount = writeableMemoryCounts[k]; + if (memCount >= MAX_WRITE_OVERLAPPED_MEMORIES) + { + FatalError("ERROR MAX WRITEABLE MEM OVERLAP"); + return; + } writeableMemorySpace[k][memCount] = m; writeableMemoryCounts[k]++; } diff --git a/arm9/source/emucore/Rip.cpp b/arm9/source/emucore/Rip.cpp index 63ea776..e1f4d1c 100644 --- a/arm9/source/emucore/Rip.cpp +++ b/arm9/source/emucore/Rip.cpp @@ -28,6 +28,7 @@ #define ROM_TAG_RELEASE_DATE 0x05 #define ROM_TAG_COMPATIBILITY 0x06 +UINT8 tag_compatibility[8] = {0}; extern UINT8 *bin_image_buf; extern UINT16 *bin_image_buf16; @@ -414,9 +415,9 @@ Rip* Rip::LoadRom(const CHAR* filename) return NULL; } - //read the magic byte (should always be $A8 or $41) + //read the magic byte (should always be $A8 or $41 or $61) int read = fgetc(infile); - if ((read != 0xA8) && (read != 0x41)) + if ((read != 0xA8) && (read != 0x41) && (read != 0x61)) { fclose(infile); FatalError("ROM MAGIC BYTE MISSING"); @@ -432,6 +433,8 @@ Rip* Rip::LoadRom(const CHAR* filename) fclose(infile); return NULL; } + + memset(tag_compatibility, 0x00, sizeof(tag_compatibility)); Rip* rip = new Rip(ID_SYSTEM_INTELLIVISION); @@ -533,6 +536,7 @@ Rip* Rip::LoadRom(const CHAR* filename) case ROM_TAG_COMPATIBILITY: { read = fgetc(infile); + tag_compatibility[0] = read; calcCrc16 = crc16_update(calcCrc16, read); // Check for ECS Supported or Required... @@ -546,6 +550,7 @@ Rip* Rip::LoadRom(const CHAR* filename) for (i = 0; i < length-1; i++) // -1 because we already processed the first byte above... { read = fgetc(infile); + tag_compatibility[1+i] = read; calcCrc16 = crc16_update(calcCrc16, read); // ------------------------------------------------------------------------ // Optional Byte 4 is of interest to us as that one has JLP stuff in it diff --git a/arm9/source/emucore/Rip.h b/arm9/source/emucore/Rip.h index 99ecbfe..f5a65ca 100644 --- a/arm9/source/emucore/Rip.h +++ b/arm9/source/emucore/Rip.h @@ -23,9 +23,9 @@ using namespace std; typedef enum _PeripheralCompatibility { - PERIPH_REQUIRED = 0, - PERIPH_OPTIONAL = 1, - PERIPH_COMPATIBLE = 2, + PERIPH_REQUIRED = 0, + PERIPH_OPTIONAL = 1, + PERIPH_COMPATIBLE = 2, PERIPH_INCOMPATIBLE = 3 } PeripheralCompatibility; @@ -34,6 +34,7 @@ typedef enum _PeripheralCompatibility #define ID_PERIPH_ECS 0x143D9A97 #define ID_PERIPH_INTELLIVOICE 0x6EFF540A +extern UINT8 tag_compatibility[]; typedef struct _CartridgeConfiguration CartridgeConfiguration; diff --git a/arm9/source/loadgame.cpp b/arm9/source/loadgame.cpp index 5b3a874..f0a8714 100644 --- a/arm9/source/loadgame.cpp +++ b/arm9/source/loadgame.cpp @@ -102,6 +102,16 @@ BOOL LoadCart(const CHAR* filename) FatalError("UNKNOWN FILE TYPE"); return FALSE; } + + // ------------------------------------------------------------------------------------------------------------------ + // The ECS uses 3 banked ROM areas... so we need to fill those in manually as we clear this array out on every load. + // ------------------------------------------------------------------------------------------------------------------ + if (bUseECS) + { + gBankerIsMappedHere[0x2][1] = 1; + gBankerIsMappedHere[0x7][0] = 1; + gBankerIsMappedHere[0xE][1] = 1; + } // --------------------------------------------------------------------- // New game is loaded... (would have returned FALSE above otherwise)