Version 4.8 - see readme for details.

This commit is contained in:
Dave Bernazzani 2025-02-15 08:24:57 -05:00
parent f116ec6863
commit b3a96e11ea
11 changed files with 87 additions and 38 deletions

Binary file not shown.

View File

@ -1,4 +1,4 @@
VERSION=4.7 VERSION=4.8
TARGNAME=A7800DS TARGNAME=A7800DS
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -33,7 +33,7 @@ Features :
Copyright : Copyright :
---------- ----------
A7800DS is Copyright 2021-2024 by Dave Bernazzani (wavemotion-dave). A7800DS is Copyright 2021-2025 by Dave Bernazzani (wavemotion-dave).
This emulator is based heavily upon ProSystem and that emulator was released This emulator is based heavily upon ProSystem and that emulator was released
in 2005 by Greg Stanton under the GNU General Public License and, as such, in 2005 by Greg Stanton under the GNU General Public License and, as such,
@ -197,6 +197,12 @@ Updates by wavemotion-dave: https://github.com/wavemotion-dave/A7800DS
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
History : History :
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
V4.8 : 15-Feb-2025 by wavemotion-dave
* High Score (HSC) now auto-saves the .hsc file after it is written by the game. The HSC button is gone.
* Smoother console button operation so that a press is registered more consistently and with better debounce.
* Improved magnifying glass icon debounce so that it registers more consistently and with better debounce.
* New game icon to align with the other emulators in the Atari lineup on the DS.
V4.7 : 11-May-2024 by wavemotion-dave V4.7 : 11-May-2024 by wavemotion-dave
* X and Y buttons now shift the screen down/up by 16 pixels so you can position the score off-screen and use these to pan up/down to see it. * X and Y buttons now shift the screen down/up by 16 pixels so you can position the score off-screen and use these to pan up/down to see it.
* Fix for Supercarts so that they start in bank 0 (Legend of Silverpeak should now load) * Fix for Supercarts so that they start in bank 0 (Legend of Silverpeak should now load)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,5 +1,5 @@
// ===================================================================================== // =====================================================================================
// Copyright (c) 2022-2024 Dave Bernazzani (wavemotion-dave) // Copyright (c) 2022-2025 Dave Bernazzani (wavemotion-dave)
// //
// Copying and distribution of this emulator, it's source code and associated // Copying and distribution of this emulator, it's source code and associated
// readme files, with or without modification, are permitted in any medium without // readme files, with or without modification, are permitted in any medium without
@ -64,6 +64,8 @@ u32 snes_adaptor __attribute__((section(".dtcm"))) = 0x00
extern u32 tiaBufIdx; extern u32 tiaBufIdx;
char fpsbuf[34]; char fpsbuf[34];
char dbgbuf[40]; char dbgbuf[40];
u8 bJustSavedHSC = 0;
u8 spamHSC = 0;
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// Some vars for listing filenames of ROMs... 1K of ROMs is plenty // Some vars for listing filenames of ROMs... 1K of ROMs is plenty
@ -170,6 +172,8 @@ void FadeToColor(unsigned char ucSens, unsigned short ucBG, unsigned char ucScr,
} }
} }
u8 tchepres_delay = 0;
u8 tchepres_value = 0;
#define tchepres(a) \ #define tchepres(a) \
keyboard_data[GameConf.DS_Pad[a]] = 1; keyboard_data[GameConf.DS_Pad[a]] = 1;
@ -347,6 +351,8 @@ void dsLoadGame(char *filename)
prosystem_Reset(); prosystem_Reset();
lastSample = 0; lastSample = 0;
bJustSavedHSC = 0;
spamHSC = 0;
if (DEBUG_DUMP) if (DEBUG_DUMP)
{ {
@ -394,6 +400,9 @@ void dsLoadGame(char *filename)
TIMER0_DATA=0; TIMER0_DATA=0;
TIMER0_CR=TIMER_ENABLE|TIMER_DIV_1024; TIMER0_CR=TIMER_ENABLE|TIMER_DIV_1024;
tchepres_delay = 0;
tchepres_value = 0;
SoundUnPause(); SoundUnPause();
} }
} }
@ -428,7 +437,7 @@ bool dsWaitOnQuit(void) {
dmaFillWords(dmaVal | (dmaVal<<16),(void*) bgGetMapPtr(bg1b),32*24*2); dmaFillWords(dmaVal | (dmaVal<<16),(void*) bgGetMapPtr(bg1b),32*24*2);
strcpy(szName,"Quit a7800DS ?"); strcpy(szName,"Quit a7800DS ?");
dsPrintValue(16-strlen(szName)/2,3,0,szName); dsPrintValue(16-strlen(szName)/2,5,0,szName);
sprintf(szName,"%s","A TO CONFIRM, B TO GO BACK"); sprintf(szName,"%s","A TO CONFIRM, B TO GO BACK");
dsPrintValue(16-strlen(szName)/2,23,0,szName); dsPrintValue(16-strlen(szName)/2,23,0,szName);
@ -978,6 +987,13 @@ ITCM_CODE void dsMainLoop(void)
memset(keyboard_data, 0x00, 15); // Not the difficulty switches which are the two bytes after this... memset(keyboard_data, 0x00, 15); // Not the difficulty switches which are the two bytes after this...
} }
// If we have recently pressed any of the console keys... keep it pressed for a minimum duration
if (tchepres_delay)
{
tchepres_delay--;
tchepres(tchepres_value);
}
scanKeys(); scanKeys();
keys_pressed = keysCurrent(); keys_pressed = keysCurrent();
@ -990,7 +1006,7 @@ ITCM_CODE void dsMainLoop(void)
touchRead(&touch); touchRead(&touch);
iTx = touch.px; iTx = touch.px;
iTy = touch.py; iTy = touch.py;
if ((iTx>8) && (iTx<55) && (iTy>154) && (iTy<171)) { // 32,160 -> 64,168 POWER if ((iTx>2) && (iTx<67) && (iTy>154) && (iTy<171)) { // POWER
SoundPause(); SoundPause();
mmEffect(SFX_KEYCLICK); // Play short key click for feedback... mmEffect(SFX_KEYCLICK); // Play short key click for feedback...
if (dsWaitOnQuit()) emu_state=A7800_QUITSTDS; if (dsWaitOnQuit()) emu_state=A7800_QUITSTDS;
@ -1005,34 +1021,28 @@ ITCM_CODE void dsMainLoop(void)
fpsDisplay = 1-fpsDisplay; gTotalAtariFrames=0; if (!fpsDisplay) dsPrintValue(0,0,0," "); fpsDisplay = 1-fpsDisplay; gTotalAtariFrames=0; if (!fpsDisplay) dsPrintValue(0,0,0," ");
dampen=60; dampen=60;
} }
else if ((iTx>63) && (iTx<105) && (iTy>154) && (iTy<171)) { // 72,160 -> 105,168 PAUSE else if ((iTx>67) && (iTx<128) && (iTy>154) && (iTy<171)) { // PAUSE
if (keys_touch == 0) mmEffect(SFX_KEYCLICK); // Play short key click for feedback... if (keys_touch == 0) mmEffect(SFX_KEYCLICK); // Play short key click for feedback...
tchepres_value = 10;
tchepres_delay = 5;
tchepres(10); tchepres(10);
} }
else if ((iTx>152) && (iTx<198) && (iTy>154) && (iTy<171)) { // 142,160 -> 175,168 SELECT else if ((iTx>128) && (iTx<193) && (iTy>154) && (iTy<171)) { // SELECT
if (keys_touch == 0) mmEffect(SFX_KEYCLICK); // Play short key click for feedback... if (keys_touch == 0) mmEffect(SFX_KEYCLICK); // Play short key click for feedback...
tchepres_value = 11;
tchepres_delay = 5;
tchepres(11); tchepres(11);
} }
else if ((iTx>208) && (iTx<251) && (iTy>154) && (iTy<171)) { // 191,160 -> 224,168 RESET else if ((iTx>193) && (iTx<254) && (iTy>154) && (iTy<171)) { // RESET
if (keys_touch == 0) mmEffect(SFX_KEYCLICK); // Play short key click for feedback... if (keys_touch == 0) mmEffect(SFX_KEYCLICK); // Play short key click for feedback...
tchepres_value = 6;
tchepres_delay = 5;
tchepres(6); tchepres(6);
} }
else if ((iTx>90) && (iTx<110) && (iTy>90) && (iTy<110)) { // Atari Logo - Activate HSC Maintenence Mode (only on High Score screen) else if ((iTx>90) && (iTx<110) && (iTy>90) && (iTy<110)) { // Atari Logo - Activate HSC Maintenence Mode (only on High Score screen)
special_hsc_entry=70; special_hsc_entry=70;
} }
else if ((iTx>115) && (iTx<144) && (iTy>154) && (iTy<171)) { // Snap HSC SRAM file else if ((iTx>69) && (iTx<180) && (iTy>21) && (iTy<62)) // Cartridge slot
if (high_score_cart_loaded)
{
dsPrintValue(13,0,0, "SAVING");
mmEffect(SFX_KEYCLICK); // Play short key click for feedback...
WAITVBL;WAITVBL;
cartridge_SaveHighScoreSram();
dsPrintValue(13,0,0, " ");
}
dampen=60;
continue;
}
else if ((iTx>69) && (iTx<180) && (iTy>22) && (iTy<62)) // Cartridge slot
{ {
SoundPause(); SoundPause();
// Find files in current directory and show it // Find files in current directory and show it
@ -1052,7 +1062,7 @@ ITCM_CODE void dsMainLoop(void)
} }
else if ((iTx>10) && (iTx<58) && (iTy>22) && (iTy<62)) // Magnifying Glass (zoom) else if ((iTx>10) && (iTx<58) && (iTy>22) && (iTy<62)) // Magnifying Glass (zoom)
{ {
toggle_zoom(); if (!keys_touch) toggle_zoom();
} }
keys_touch=1; keys_touch=1;
@ -1063,11 +1073,11 @@ ITCM_CODE void dsMainLoop(void)
last_keys_pressed = keys_pressed; last_keys_pressed = keys_pressed;
if ((myCartInfo.cardctrl1 != SNES)) if ((myCartInfo.cardctrl1 != SNES))
{ {
if ( (keys_pressed & KEY_SELECT) ) { tchepres(11); } // BUTTON SELECT if ( (keys_pressed & KEY_SELECT) ) { tchepres_value = 11; tchepres_delay = 5;tchepres(11); } // BUTTON SELECT
} }
if ((myCartInfo.cardctrl1 != TWIN) && (myCartInfo.cardctrl1 != SNES)) if ((myCartInfo.cardctrl1 != TWIN) && (myCartInfo.cardctrl1 != SNES))
{ {
if ( (keys_pressed & KEY_START) ) {tchepres(10);} // BUTTON PAUSE if ( (keys_pressed & KEY_START) ) { tchepres_value = 10; tchepres_delay = 5; tchepres(10); } // BUTTON PAUSE
} }
if (myCartInfo.cardctrl1 == SOTA) if (myCartInfo.cardctrl1 == SOTA)
{ {
@ -1124,6 +1134,26 @@ ITCM_CODE void dsMainLoop(void)
// ------------------------------------------------------------- // -------------------------------------------------------------
if (TIMER1_DATA >= 32728) // 1000MS (1 sec) if (TIMER1_DATA >= 32728) // 1000MS (1 sec)
{ {
if (bHSC_dirty) // Check to see if the High Score area has changed ... if so, snap out the .hsc file
{
if (high_score_cart_loaded && myCartInfo.hsc) // Check if HSC is enabled
{
if (++spamHSC <= 8) // Check that we haven't been spamming the HSC saving...
{
dsPrintValue(11,0,0, "HSC SAVING");
cartridge_SaveHighScoreSram();
bJustSavedHSC = 1;
}
}
bHSC_dirty = 0;
}
else if (bJustSavedHSC)
{
bJustSavedHSC = 0;
if (spamHSC <= 8) spamHSC = 0;
dsPrintValue(11,0,0, " ");
}
TIMER1_CR = 0; TIMER1_CR = 0;
TIMER1_DATA = 0; TIMER1_DATA = 0;
TIMER1_CR=TIMER_ENABLE | TIMER_DIV_1024; TIMER1_CR=TIMER_ENABLE | TIMER_DIV_1024;

View File

@ -1,5 +1,5 @@
// ===================================================================================== // =====================================================================================
// Copyright (c) 2022-2024 Dave Bernazzani (wavemotion-dave) // Copyright (c) 2022-2025 Dave Bernazzani (wavemotion-dave)
// //
// Copying and distribution of this emulator, it's source code and associated // Copying and distribution of this emulator, it's source code and associated
// readme files, with or without modification, are permitted in any medium without // readme files, with or without modification, are permitted in any medium without

View File

@ -218,6 +218,9 @@ bool cartridge_SaveHighScoreSram(void)
return false; // If we didn't load the high score cartridge, or don't have an HSC enabled cart: don't save. return false; // If we didn't load the high score cartridge, or don't have an HSC enabled cart: don't save.
} }
// Make sure something actually changed before writing...
if (memcmp(high_score_sram, memory_ram+HS_SRAM_START, HS_SRAM_SIZE) != 0)
{
memcpy(high_score_sram, memory_ram+HS_SRAM_START, HS_SRAM_SIZE); // Copy from main memory to SRAM buffer memcpy(high_score_sram, memory_ram+HS_SRAM_START, HS_SRAM_SIZE); // Copy from main memory to SRAM buffer
make_hsc_name(); // HSC filename is same as base filename with .hsc extension make_hsc_name(); // HSC filename is same as base filename with .hsc extension
@ -229,6 +232,7 @@ bool cartridge_SaveHighScoreSram(void)
fwrite(high_score_sram, HS_SRAM_SIZE, 1, handle); fwrite(high_score_sram, HS_SRAM_SIZE, 1, handle);
fclose(handle); fclose(handle);
} }
}
return true; // We at least made the attempt to write out the .hsc save file return true; // We at least made the attempt to write out the .hsc save file
} }
@ -266,6 +270,8 @@ static bool cartridge_LoadHighScoreSram(void)
memory_Write(HS_SRAM_START + i, high_score_sram[i]); memory_Write(HS_SRAM_START + i, high_score_sram[i]);
} }
bHSC_dirty = 0; // We don't consider the init of SRAM directly above to be a 'write' (no need to persist)
return true; // HSC SRAM is ready to go! return true; // HSC SRAM is ready to go!
} }

View File

@ -30,6 +30,7 @@
byte memory_ram[MEMORY_SIZE] ALIGN(32) = {0}; byte memory_ram[MEMORY_SIZE] ALIGN(32) = {0};
u8 *is_memory_writable = (u8*)0x06820000; u8 *is_memory_writable = (u8*)0x06820000;
u32 snes_bit_pos = 0; u32 snes_bit_pos = 0;
u8 bHSC_dirty = 0;
extern bool write_only_pokey_at_4000; extern bool write_only_pokey_at_4000;
@ -48,6 +49,7 @@ void memory_Reset( )
ptr[index] = 0xFFFF; ptr[index] = 0xFFFF;
} }
bHSC_dirty = 0;
snes_bit_pos = 0; snes_bit_pos = 0;
} }
@ -147,7 +149,10 @@ ITCM_CODE void memory_Write(word address, byte data)
memory_ram[address ^0x0100] = data; memory_ram[address ^0x0100] = data;
} }
} }
//else if ((address & 0xF800) == 0x1000) // HSC RAM - someday we might trigger on this and auto-save the .hsc SRAM file else if ((address & 0xF800) == 0x1000) // HSC RAM - set the dirty bit so we persist the .hsc file in the main loop
{
bHSC_dirty = 1;
}
memory_ram[address] = data; memory_ram[address] = data;
return; return;

View File

@ -33,6 +33,8 @@
#include "shared.h" #include "shared.h"
extern u8 bHSC_dirty;
extern byte memory_ram[MEMORY_SIZE]; extern byte memory_ram[MEMORY_SIZE];
extern void memory_Reset( ); extern void memory_Reset( );

BIN
logo.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 630 B