Version 4.6 with full support for the .a78 v4 headers, improved HSC support, and other sundry improvements. See readme.md for details.

This commit is contained in:
Dave Bernazzani 2024-05-06 09:02:41 -04:00
parent 30f0a004c0
commit 90abe106ce
20 changed files with 359 additions and 181 deletions

Binary file not shown.

View File

@ -1,4 +1,4 @@
VERSION=4.5b
VERSION=4.6
TARGNAME=A7800DS
#---------------------------------------------------------------------------------

128
README.md
View File

@ -23,10 +23,10 @@ Features :
All popular bank-switching schemes are supported including an extra 16K of RAM at 4000h.
Pokey support at 4000h, 800h and 450h - change this in Configuration if it's not auto-detected.
Starting with version 4.3, the new Banksets scheme is fully supported - this new banking/memory handling
is designed for homebrew authors to provide increased ROM density and improved packing and access
of graphics data vs code. This allows for games that would have been difficult or impossible without
the scheme. See http://7800.8bitdev.org/index.php/Bankset_Bankswitching for more details.
The new Banksets scheme is fully supported - this new banking/memory handling is designed
for homebrew authors to provide increased ROM density and improved packing and access of
graphics data vs code. This allows for games that would have been difficult or impossible
without the scheme. See http://7800.8bitdev.org/index.php/Bankset_Bankswitching for more details.
Add highscore.rom for 7800 High Score saving. This can be in /roms/bios, /data/bios
or in the same directory as the emulator. It's worth the effort to track down the highscore.rom file!
@ -35,11 +35,27 @@ Copyright :
----------
A7800DS is Copyright 2021-2024 by Dave Bernazzani (wavemotion-dave).
Copying and distribution of this emulator, it's source code and associated
readme files, with or without modification, are permitted in any medium without
royalty provided this copyright notice is used and wavemotion-dave (Phoenix-Edition),
Alekmaul (original port) and Greg Stanton (ProSystem Emulator) are thanked profusely.
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,
this derived work is released in the same manner. The original license text
that Greg used is included here:
```
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
```
Philosophy :
----------
@ -56,7 +72,7 @@ Known Issues and Limitations:
- Lightgun is not supported.
- Paddles are not supported.
- Games greater than 1MB (1024K + 128b header) are not supported.
- Only one Pokey is supported at 4000h, 800h and 450h (no Dual Pokey)
- Only one Pokey is supported at 4000h, 800h or 450h (no Dual Pokey)
- XM is not supported (beyond HSC and Pokey)
--------------------------------------------------------------------------------
@ -132,9 +148,9 @@ Credits:
--------------------------------------------------------------------------------
* Thanks Wintermute for devkitpro and libnds (http://www.devkitpro.org).
* Greg Stanton for ProSystem source code (https://home.comcast.net/~gscottstanton/) an Atari 7800 emulator.
* zx81 (http://zx81.zx81.free.fr/serendipity_fr/) for PSP A7800 version (that helped me a lot to understand ProSystem).
* zx81 (http://zx81.zx81.free.fr/serendipity_fr/) for PSP A7800 version (that helped to understand ProSystem).
* raz0red (http://www.twitchasylum.com/forum/viewtopic.php?t=519) for WII7800 (that helped me to fix some timing problems).
* The folks at AtariAge who helped weed out many of the old ProSystem Maria rendering bugs.
* The folks at AtariAge who helped weed out many of the old ProSystem Maria rendering and timing issues.
* The MAXMOD audio library is Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org). See https://github.com/devkitPro/maxmod
--------------------------------------------------------------------------------
@ -149,11 +165,12 @@ Updates by wavemotion-dave: https://github.com/wavemotion-dave/A7800DS
--------------------------------------------------------------------------------
History :
--------------------------------------------------------------------------------
V4.5b : 05-May-2024 by wavemotion-dave
V4.6 : 06-May-2024 by wavemotion-dave
* Each game that utilizes a High Score Cart (HSC) gets its own 2K .hsc file
* Improved High Score Cart (HSC) emulation - improved initialization of the SRAM contents.
* Sanity checks added so that carts marked as 'NORMAL' (or selected as such) but are larger than 48K will not corrupt memory.
* New magnifying glass icon to ZOOM (and center) the display 1:1 with real 7800 output. This will crop on a DS/DSi since it only has 256x192 but very useful to toggle the 1:1 zoom for High Score Entries, etc.
* Starting to lay groundwork support for .a78 V4 headers...
* Support for .a78 V4 headers (will fall back to V3 if not available)
V4.5 : 18-Nov-2022 by wavemotion-dave
* SNES2Atari adaptor supported.
@ -345,86 +362,3 @@ V1.1 : 09-Dec-2020 by wavemotion-dave
V1.0 : 24/05/2011
* Initial release based on my a320 version (which is based on Prosystem 1.0.3)
* Compiled with last version of Devkitpro/libnds, so DSi compatible \o/
Compatibility Table (on the faster DSi)
```
GAME MD5SUM HSC FPS NOTES
========================================================================================================================
Ace Of Aces 0be996d25144966d5541c9eb4919b289 NO 60 Near perfect
Alien Brigade 877dcc97a775ed55081864b2dbf5f1e2 NO 60 Near perfect
Arkanoid Demo 212ee2a6e66d8bb7fbf26f343cc8dc19 NO 60 Playable though paddles would be nice.
Asteroids 07342c78619ba6ffcc61c10e907e3b50 YES 60 Near perfect
Asteroids Deluxe a65f79ad4a0bbdecd59d5f7eb3623fd7 YES 60 Near perfect
Astro Blaster 3d38281ed8a8d8c7cd457a18c92c8604 YES 60 Near perfect
Astro Fighter a51e5df28a0fe8c52e9d28fb5f8e44a6 YES 60 Near perfect
Baby Pac Man 7cdfbe37634e7dcd4dc67db7edbcd3ba NO 60 Near perfect
Ballblazer 8fc3a695eaea3984912d98ed4a543376 NO 60 Near perfect
Barnyard Blaster 42682415906c21c6af80e4198403ffda NO 60 Needs Lightgun Support (not implemented)
Basketbrawl f5f6b69c5eb4b55fc163158d1a6b423e NO 60 Near perfect
Beef Drop (Final) 78b1061d651ef806becac1dd3fda29a0 YES 60 Near perfect
BonQ (Final) 9fa7743a016c9b7015ee1d386326f88e YES 60 Near perfect
Centipede 5a09946e57dbe30408a8f253a28d07db YES 60 Near perfect
Choplifter 93e4387864b014c155d7c17877990d1e NO 60 Near perfect
Commando 2e8e28f6ad8b9b9267d518d880c73ebb NO 60 Near perfect
Crack'ed db691469128d9a4217ec7e315930b646 NO 60 Would be better with lightgun support.
Crossbow a94e4560b6ad053a1c24e096f1262ebf NO 60 Would be better with lightgun support.
Dark Chambers 179b76ff729d4849b8f66a502398acae NO 60 Near perfect
Desert Falcon 95ac811c7d27af0032ba090f28c107bd NO 60 Near perfect
Dig Dug 731879ea82fc0ca245e39e036fe293e6 YES 60 Near perfect
Donkey Kong 19f1ee292a23636bd57d408b62de79c7 NO 60 Near perfect
Donkey Kong Jr 5e332fbfc1e0fc74223d2e73271ce650 NO 60 Near perfect
Donkey Kong XM Demo c3107d3e3e17d67e3a11d47a5946a4f3 NO 60 Near perfect
Double Dragon 543484c00ba233736bcaba2da20eeea9 NO 60 Near perfect
Dragon's Descent 94009ccfdcd4f55d24033ca06269ba6a NO 60 Near perfect
Drakers Quest I fab1290f9a4c4f2b4d831c8a57f969f5 NO 60 Near perfect
Drakers Quest II a9f29004412621f20ad9f5c51cc11486 NO 60 Near perfect
Dungeon Stalker b3143adbbb7d7d189e918e5b29d55a72 YES 60 Near perfect
E.X.O Alpha 12 faea27017447dd8bae677d91125a8135 YES 60 Near perfect
F-18 Hornet 2251a6a0f3aec84cc0aff66fc9fa91e8 NO 60 A few small graphical glitches but playable.
Failsafe (homebrew) 6287727ab36391a62f728bbdee88675c YES 60 Near perfect
Fatal Run d25d5d19188e9f149977c49eb0367cd1 NO 60 Near perfect
Food Fight cf76b00244105b8e03cdc37677ec1073 YES 60 Near perfect
Frenzy (with Berzerk) e7d89669a7f92ec2cc99d9663a28671c YES 60 Near perfect
Froggie 6053233cb59c0b4ca633623fd76c4576 YES 60 Near perfect
Galaga fb8d803b328b2e442548f7799cfa9a4a YES 60 Near perfect
Hat Trick fd9e78e201b6baafddfd3e1fbfe6ba31 NO 60 Near perfect
Ikari Warriors c3672482ca93f70eafd9134b936c3feb NO 60 Near perfect
Impossible Mission baebc9246c087e893dfa489632157180 NO 60 Near perfect
Jinks 045fd12050b7f2b842d5970f2414e912 NO 60 Near perfect
Joust f18b3b897a25ab3885b43b4bd141b396 YES 60 Near perfect
Jr. Pac-Man e54edc299e72d22d0ba05d16f3393e8c YES 60 Near perfect
Klax 17b3b764d33eae9b5260f01df7bb9d2f NO 60 Near perfect
Karateka c3a5a8692a423d43d9d28dd5b7d109d9 NO 60 Minor glitches.
Kung Fu Master f57d0af323d4e173fb49ed447f0563d7 NO 60 Near perfect
Mario Bros. 431ca060201ee1f9eb49d44962874049 NO 60 Near perfect
Meteor Shower c3f6201d6a9388e860328c963a3301cc YES 60 Near perfect - my favorite homebrew!
Midnight Mutants bc1e905db1008493a9632aa83ab4682b NO 60 Near perfect
Moon Cresta 9ff38ea62004201d870caa8bd9463525 YES 60 Near perfect
Ms. Pac-Man fc0ea52a9fac557251b65ee680d951e5 YES 60 Near perfect
Ninja Golf 220121f771fc4b98cef97dc040e8d378 NO 60 Near perfect
One On One 74569571a208f8b0b1ccfb22d7c914e1 NO 60 Near perfect
Pac-Man Collection 5013b69cb05b21a1194ce48517df7bfc YES 60 Near perfect
Pac-Man Collection 40th 1330d23ebad9b5ded92ebeacdf305abd YES 60 Near perfect - Damn this is one fine collection!
Planet Smashers 33aea1e2b6634a1dec8c7006d9afda22 NO 60 Near perfect
Plutos 86546808dc60961cdb1b20e761c50ab1 NO 60 Near perfect
Pole Position II 584582bb09ee8122e7fc09dc7d1ed813 NO 60 Near perfect
Popeye Demo 2.9 640c7827fe63082efbaffc13f7983744 YES 60 Near perfect.
Spire of the Ancients 19844117863cd38d4e1e4cbc867ae599 NO 60 Near perfect
Rampage ac03806cef2558fc795a7d5d8dba7bc0 NO 60 Near perfect
Realsports Baseball 383ed9bd1efb9b6cb3388a777678c928 NO 60 Any voice rendering is slow.
Robotron 66ecaafe1b82ae68ffc96267aaf7a4d7 YES 60 Near perfect
Scramble a3a85e507d6f718972b1464ce1aaf8a4 YES 60 Near perfect
Scrapyard Dog 980c35ae9625773a450aa7ef51751c04 NO 60 Near perfect
Serpentine 9bd70c06d3386f76f8162881699a777a YES 60 Near perfect
Space Duel 771cb4609347657f63e6f0eb26036e35 YES 60 Near perfect
Space Invaders 6adf79558a3d7f5beca1bb8d34337417 YES 60 Near perfect
Summer Games cbb0746192540a13b4c7775c7ce2021f NO 60 Plays fine - font hard to read on small screen.
Super Skatebordin 59b5793bece1c80f77b55d60fb39cb94 NO 60 Near perfect
Super Circus Atariage 81cee326b99d6831de10a566e338bd25 YES 60 Near perfect
Time Salvo a60e4b608505d1fb201703b266f754a7 YES 60 Near perfect
UniWarS 79df20ee86a989e669158bcb9d113e8a YES 60 Near perfect
Winter Games 3799d72f78dda2ee87b0ef8bf7b91186 NO 60 Plays fine - font hard to read on small screen.
Xenophobe 05fb699db9eef564e2fe45c568746dbc NO 60 Near perfect
Xevious d7dc17379aa25e5ae3c14b9e780c6f6d YES 60 Near perfect
```

Binary file not shown.

View File

@ -77,8 +77,6 @@ int main() {
installSystemFIFO();
//installSoundEmuFIFO();
irqSet(IRQ_VCOUNT, VcountHandler);
irqSet(IRQ_VBLANK, VblankHandler);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -7,6 +7,22 @@
// Alekmaul (original port) and Greg Stanton (ProSystem Emulator) are thanked profusely.
//
// A7800DS emulator is offered as-is, without any warranty.
//
// The original GPL license:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// =====================================================================================
#include <nds.h>
#include <nds/fifomessages.h>
@ -90,10 +106,10 @@ static void DumpDebugData(void)
}
extern byte last_illegal_opcode;
if (last_illegal_opcode >= 0)
if (last_illegal_opcode > 0)
{
sprintf(fpsbuf, "ILLOP=%02X", last_illegal_opcode);
dsPrintValue(24,21,0, fpsbuf);
sprintf(fpsbuf, "ILLEGAL OP=%02X", last_illegal_opcode);
dsPrintValue(10,23,0, fpsbuf);
}
}
@ -281,7 +297,7 @@ void dsFreeEmu(void)
void dsLoadGame(char *filename)
{
unsigned int index;
u16 index;
SoundPause();
@ -311,9 +327,10 @@ void dsLoadGame(char *filename)
if (DEBUG_DUMP)
{
char dbgbuf[32];
char dbgbuf[33];
extern char header[];
extern word cardtype;
sprintf(dbgbuf, "CARDTYPE: %04X", cardtype);
sprintf(dbgbuf, "V%c CTV3: %04X V4MT: %04X AUD:%02X", '0'+header[0], cardtype, ((u16)header[64]<<8)|header[65], header[67]);
dsPrintValue(0,21,0, (char*)dbgbuf);
dsPrintValue(0,22,0, (char*)cartridge_digest);
}
@ -427,7 +444,7 @@ void _putchar(char character) {}; // Not used but needed to link printf()
void dsDisplayFiles(unsigned int NoDebGame,u32 ucSel)
{
unsigned int ucGame;
u16 ucGame;
u8 maxLen;
// Display all games if possible
@ -461,9 +478,9 @@ void dsDisplayFiles(unsigned int NoDebGame,u32 ucSel)
unsigned int dsWaitForRom(void)
{
bool bDone=false, bRet=false;
u32 ucHaut=0x00, ucBas=0x00,ucSHaut=0x00, ucSBas=0x00,romSelected= 0, firstRomDisplay=0,nbRomPerPage, uNbRSPage, uLenFic=0;
s32 ucFlip=0, ucFlop=0;
u8 bDone=false, bRet=false;
u16 ucHaut=0x00, ucBas=0x00,ucSHaut=0x00, ucSBas=0x00,romSelected= 0, firstRomDisplay=0,nbRomPerPage, uNbRSPage, uLenFic=0;
s16 ucFlip=0, ucFlop=0;
decompress(bgFileSelTiles, bgGetGfxPtr(bg0b), LZ77Vram);
decompress(bgFileSelMap, (void*) bgGetMapPtr(bg0b), LZ77Vram);
@ -825,27 +842,27 @@ __attribute__ ((noinline)) void handle_LR_keys(unsigned int keys_pressed)
}
if (scale_screen_dampen > 5)
{
if ((keys_pressed & KEY_R) && (keys_pressed & KEY_UP)) { myCartInfo.yOffset++; bRefreshXY = true; }
if ((keys_pressed & KEY_R) && (keys_pressed & KEY_DOWN)) { myCartInfo.yOffset--; bRefreshXY = true; }
if ((keys_pressed & KEY_R) && (keys_pressed & KEY_UP)) { myCartInfo.yOffset++; bRefreshXY = true; }
if ((keys_pressed & KEY_R) && (keys_pressed & KEY_DOWN)) { myCartInfo.yOffset--; bRefreshXY = true; }
if ((keys_pressed & KEY_R) && (keys_pressed & KEY_LEFT)) { myCartInfo.xOffset++; bRefreshXY = true; }
if ((keys_pressed & KEY_R) && (keys_pressed & KEY_RIGHT)) { myCartInfo.xOffset--; bRefreshXY = true; }
if ((keys_pressed & KEY_L) && (keys_pressed & KEY_UP)) if (myCartInfo.yScale < 234) { myCartInfo.yScale++; bRefreshXY = true; }
if ((keys_pressed & KEY_L) && (keys_pressed & KEY_DOWN)) if (myCartInfo.yScale > 192) { myCartInfo.yScale--; bRefreshXY = true; }
if ((keys_pressed & KEY_L) && (keys_pressed & KEY_UP)) if (myCartInfo.yScale < 234) { myCartInfo.yScale++; bRefreshXY = true; }
if ((keys_pressed & KEY_L) && (keys_pressed & KEY_DOWN)) if (myCartInfo.yScale > 192) { myCartInfo.yScale--; bRefreshXY = true; }
if ((keys_pressed & KEY_L) && (keys_pressed & KEY_RIGHT)) if (myCartInfo.xScale < 320) { myCartInfo.xScale++; bRefreshXY = true; }
if ((keys_pressed & KEY_L) && (keys_pressed & KEY_LEFT)) if (myCartInfo.xScale > 192) { myCartInfo.xScale--; bRefreshXY = true; }
if ((keys_pressed & KEY_L) && (keys_pressed & KEY_LEFT)) if (myCartInfo.xScale > 192) { myCartInfo.xScale--; bRefreshXY = true; }
scale_screen_dampen=0;
} else scale_screen_dampen++;
}
}
// Toggle full 320x256
__attribute__ ((noinline)) void toggle_zoom(void)
static s16 last_xScale = 0;
static s16 last_yScale = 0;
static s16 last_xOffset = 0;
static s16 last_yOffset = 0;
__attribute__ ((noinline)) void toggle_zoom(void)
{
static s16 last_xScale = 0;
static s16 last_yScale = 0;
static s16 last_xOffset = 0;
static s16 last_yOffset = 0;
if (last_xScale == 0)
{
last_xScale = myCartInfo.xScale;
@ -896,6 +913,7 @@ ITCM_CODE void dsMainLoop(void)
case A7800_PLAYINIT:
dsShowScreenEmu();
emu_state = A7800_PLAYGAME;
last_xScale = 0;
break;
case A7800_PLAYGAME:
@ -904,7 +922,7 @@ ITCM_CODE void dsMainLoop(void)
// 655 -> 50 fps and 546 -> 60 fps
if (!full_speed)
{
while(TIMER0_DATA < (546*atari_frames))
while(TIMER0_DATA < (546*atari_frames)) // We are only supporting NTSC timing
;
}
@ -976,7 +994,7 @@ ITCM_CODE void dsMainLoop(void)
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;
}
else if ((iTx>115) && (iTx<144) && (iTy>154) && (iTy<171)) { // Snap HSC Sram
else if ((iTx>115) && (iTx<144) && (iTy>154) && (iTy<171)) { // Snap HSC SRAM file
if (high_score_cart_loaded)
{
dsPrintValue(13,0,0, "SAVING");

View File

@ -1,3 +1,29 @@
// =====================================================================================
// Copyright (c) 2022-2024 Dave Bernazzani (wavemotion-dave)
//
// Copying and distribution of this emulator, it's source code and associated
// readme files, with or without modification, are permitted in any medium without
// royalty provided this copyright notice is used and wavemotion-dave (Phoenix-Edition),
// Alekmaul (original port) and Greg Stanton (ProSystem Emulator) are thanked profusely.
//
// A7800DS emulator is offered as-is, without any warranty.
//
// The original GPL license:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// =====================================================================================
#ifndef _A7800UTILS_H
#define _A7800UTILS_H

View File

@ -1,9 +1,29 @@
// =====================================================================================================
// Stella DSi - Improved Version by Dave Bernazzani (wavemotion)
// =====================================================================================
// Copyright (c) 2022-2024 Dave Bernazzani (wavemotion-dave)
//
// See readme.txt for a list of everything that has changed in the baseline 1.0 code.
// =====================================================================================================
// Copying and distribution of this emulator, it's source code and associated
// readme files, with or without modification, are permitted in any medium without
// royalty provided this copyright notice is used and wavemotion-dave (Phoenix-Edition),
// Alekmaul (original port) and Greg Stanton (ProSystem Emulator) are thanked profusely.
//
// A7800DS emulator is offered as-is, without any warranty.
//
// The original GPL license:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// =====================================================================================
#include <nds.h>
#include <stdio.h>
#include <fat.h>
@ -26,6 +46,8 @@ static int display_options_list(bool bFullDisplay);
extern void dsPrintValue(int x, int y, unsigned int isSelect, char *pchStr);
extern void dsShowScreenMain(bool);
char strBuf[35];
// ---------------------------------------------------------------------------
// Write out the A7800DS.DAT configuration file to capture the settings for
// each game. We can store more than 350 game settings!
@ -187,7 +209,7 @@ const struct options_t Game_Option_Table[] =
{"X OFFSET", 2, {"-50", "+50"}, (u8*)&myCartInfo.xOffset, 2},
{"Y OFFSET", 2, {"-50", "+50"}, (u8*)&myCartInfo.yOffset, 2},
{"X SCALE", 2, {"+200", "+320"}, (u8*)&myCartInfo.xScale, 2},
{"Y SCALE", 2, {"+180", "+256"}, (u8*)&myCartInfo.yScale, 2},
{"Y SCALE", 2, {"+180", "+234"}, (u8*)&myCartInfo.yScale, 2},
{"X JIGGLE", 1, {"+1", "+256"}, (u8*)&myCartInfo.xJiggle, 2},
{"Y JIGGLE", 1, {"+1", "+256"}, (u8*)&myCartInfo.yJiggle, 2},
@ -198,7 +220,6 @@ const struct options_t Game_Option_Table[] =
void display_line(u8 idx, u8 highlight)
{
char strBuf[35];
if (Game_Option_Table[idx].isNumeric == 1) // Unsigned 8 bit
{
sprintf(strBuf, " %-11s : %-15d", Game_Option_Table[idx].label, *(Game_Option_Table[idx].option_val));

View File

@ -1,8 +1,29 @@
// =====================================================================================================
// Stella DSi - Improved Version by Dave Bernazzani (wavemotion)
// =====================================================================================
// Copyright (c) 2022-2024 Dave Bernazzani (wavemotion-dave)
//
// See readme.txt for a list of everything that has changed in the baseline 1.0 code.
// =====================================================================================================
// Copying and distribution of this emulator, it's source code and associated
// readme files, with or without modification, are permitted in any medium without
// royalty provided this copyright notice is used and wavemotion-dave (Phoenix-Edition),
// Alekmaul (original port) and Greg Stanton (ProSystem Emulator) are thanked profusely.
//
// A7800DS emulator is offered as-is, without any warranty.
//
// The original GPL license:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// =====================================================================================
#ifndef __CONFIG_H
#define __CONFIG_H

View File

@ -30,6 +30,7 @@
char cartridge_title[256];
byte cartridge_digest[256];
char cartridge_filename[256];
byte header[128] = {0}; // We might have a header... this will buffer it
word cardtype = 0x0000;
bool write_only_pokey_at_4000 = false;
@ -158,10 +159,21 @@ void cartridge_SwapRAM_DragonFlyStyle(u8 data)
// ----------------------------------------------------------------------------
// ReadHeader
// Atari 7800 carts come in two major flavors... .bin is just the flat
// binary of the game ROM and does not contain any information about
// what kind of cartridge it is - we can only guess by using the internal
// database and/or the size of the ROM (i.e. 128K ROMs are usually SUPERCART).
//
// But .a78 files add a 128 byte header at the front of the game ROM and give
// information about what kind of ROM mapper is used, sound options, controller
// options, etc. And there are multiple versions of the header - we currently
// support the long-standing V3 header and the newer (2023) V4 specifications.
// ----------------------------------------------------------------------------
char temp[33] = {0};
static void cartridge_ReadHeader(const byte* header) {
uint index;
char temp[33] = {0};
memset(temp, 0x00, sizeof(temp));
for(index = 0; index < 32; index++) {
temp[index] = header[index + 17];
}
@ -180,7 +192,7 @@ static void cartridge_ReadHeader(const byte* header) {
// bit 2 = ram at $4000
// bit 3 = rom at $4000
// bit 4 = second to last bank at $4000
// bit 4 = second to last bank at $4000 (EXFIX)
// bit 5 = banked ram
// bit 6 = pokey at $450
// bit 7 = mirror ram at $4000
@ -201,8 +213,8 @@ static void cartridge_ReadHeader(const byte* header) {
if (cardtype & 0x0002) myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART;
if (cardtype & 0x0004) myCartInfo.cardtype = ((cardtype & 0x0002) ? CARTRIDGE_TYPE_SUPERCART_RAM : CARTRIDGE_TYPE_FLAT_WITH_RAM);
if (cardtype & 0x0008) myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_LARGE;
if (cardtype & 0x0010) myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_ROM;
if (cardtype & 0x0008) myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_LARGE; // EXROM
if (cardtype & 0x0010) myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_ROM; // EXFIX
if (cardtype & 0x0020) myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_RAMX2;
if (cardtype & 0x0100) myCartInfo.cardtype = CARTRIDGE_TYPE_ACTIVISION;
if (cardtype & 0x0200) myCartInfo.cardtype = CARTRIDGE_TYPE_ABSOLUTE;
@ -280,13 +292,112 @@ static void cartridge_ReadHeader(const byte* header) {
// bit 1 : AtariVox/SaveKey
myCartInfo.hsc = (header[58]&1 ? HSC_YES:HSC_NO);
myCartInfo.dma_adjust = 0;
last_bank = 255;
last_ex_ram_bank = 0;
ex_ram_bank = 0;
last_ex_ram_bank_df = 0;
write_only_pokey_at_4000 = false;
ex_ram_bank_df = 0;
// ----------------------------------------------------------------------------
// Now check for the V4 extended header which overrides anything done above...
// The V4 header is mainly for mappers and audio support. Everything else
// is handled by the fields in V3 above.
// ----------------------------------------------------------------------------
if (header[0] == 0x04)
{
// Mapper:
// 0 = Linear
// 1 = SuperGame
// 2 = Activision
// 3 = Absolute
// 4 = Souper
switch (header[64])
{
case 0: // Linear
// Mapper Options:
// bit 7 : Bankset ROM
// bits 0-1 : Option at @4000 (0=none, 1=16K RAM, 2=8K EXRAM/A8, 3=32K EXRAM/M2)
if (header[65] & 0x80)
{
switch (header[65] & 0x03)
{
case 0: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS; break;
case 1: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS_RAM; break;
case 2: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS; break;
case 3: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS_HALTRAM; break;
}
}
else
{
switch (header[65] & 0x03)
{
case 0: myCartInfo.cardtype = CARTRIDGE_TYPE_NORMAL; break;
case 1: myCartInfo.cardtype = CARTRIDGE_TYPE_FLAT_WITH_RAM; break;
case 2: myCartInfo.cardtype = CARTRIDGE_TYPE_FRACTALUS; break;
case 3: break; // There is no 32K of EXRAM/M2 for non Bankset (not supported - don't change anything detected by V3 header)
}
}
break;
case 1: // Super Game
// Mapper Options:
// bit 7 : Bankset ROM
// bits 0-2 : Option at @4000 (0=none, 1=16K RAM, 2=8K EXRAM/A8, 3=32K EXRAM/M2, 4=EXROM, 5=EXFIX, 6=32k EXRAM/X2)
if (header[65] & 0x80)
{
switch (header[65] & 0x07)
{
case 0: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS; break; // No option
case 1: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS_RAM; break; // 16K RAM
case 2: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS; break; // 8K EXRAM/A8
case 3: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS_HALTRAM; break; // 32K EXRAM/M2
case 6: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS_HALTRAM; break; // 32K EXRAM/X2
default: myCartInfo.cardtype = CARTRIDGE_TYPE_BANKSETS; break; // Best we can do - mapper option doesn't make sense to us
}
}
else
{
switch (header[65] & 0x07)
{
case 0: myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART; break; // No option
case 1: myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_RAM; break; // 16K RAM
case 2: break; // 8K EXRAM/A8 (not supported - don't change anything detected by V3 header)
case 3: myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_RAMX2; break; // 32K EXRAM/M2
case 4: myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_LARGE; break; // EXROM
case 5: myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_ROM; break; // EXFIX
case 6: myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_RAMX2; break; // 32K EXRAM/X2
default: break; // Unused (not supported - don't change anything detected by V3 header)
}
}
break;
case 2: // Activision
myCartInfo.cardtype = CARTRIDGE_TYPE_ACTIVISION;
break;
case 3: // Absolute
myCartInfo.cardtype = CARTRIDGE_TYPE_ABSOLUTE;
break;
case 4: // Souper (Ricky & Vicky)
myCartInfo.cardtype = CARTRIDGE_TYPE_SUPERCART_RAM; // TODO: This is wrong. Should be SOUPER but not yet supported.
break;
}
// v4+ audio:
// bit 5 : ADPCM Audio Stream @420
// bit 4 : COVOX @430
// bit 3 : YM2151 @460
// bits 0-2 : POKEY (0=none, 1=@440, 2=@450, 3=@450+@440, 4=@800, 5=@4000)
switch (header[67] & 0x07)
{
case 0: myCartInfo.pokeyType = POKEY_NONE; break;
case 1: myCartInfo.pokeyType = POKEY_NONE; break; // Pokey at 440 not supported
case 2: myCartInfo.pokeyType = POKEY_AT_450; break;
case 3: myCartInfo.pokeyType = POKEY_AT_450; break; // Dual pokey not supported
case 4: myCartInfo.pokeyType = POKEY_AT_800; break;
case 5: myCartInfo.pokeyType = POKEY_AT_4000; break;
}
}
myCartInfo.dma_adjust = 0;
last_bank = 255;
last_ex_ram_bank = 0;
ex_ram_bank = 0;
last_ex_ram_bank_df = 0;
write_only_pokey_at_4000 = false;
ex_ram_bank_df = 0;
if (isDS_LITE) shadow_ram = ex_ram_bank ? (u8*)(ex_ram_buffer+0x0000) : (u8*)(ex_ram_buffer+0x4000); // for DS-Lite
else shadow_ram = ex_ram_bank ? (u8*)0x06830000 : (u8*)0x06834000; // // Only for the DSi.. see DS_LITE handling above
shadow_ram -= 0x4000; // Makes for faster indexing in Memory.c
@ -309,7 +420,6 @@ static bool _cartridge_Load(uint size)
memset(banksets_memory, 0xFF, sizeof(banksets_memory)); // Clear the banksets ROM memory area
memset(banksets_memory+0x4000, 0x00, 0x4000); // Clear banksets RAM memory area
static byte header[128] = {0}; // We might have a header... this will buffer it
for(index = 0; index < 128; index++)
{
header[index] = cartridge_buffer[index];
@ -614,20 +724,20 @@ void cartridge_Release( )
// These values need to be reset so that moving between carts works
// consistently. This seems to be a ProSystem emulator bug.
//
myCartInfo.cardtype = CT_NORMAL;
myCartInfo.region = NTSC;
myCartInfo.pokeyType = POKEY_NONE;
myCartInfo.hsc = false;
myCartInfo.cardctrl1 = 0;
myCartInfo.cardctrl2 = 0;
myCartInfo.hasHeader = false;
myCartInfo.dma_adjust = 0;
last_bank = 255;
last_ex_ram_bank = 0;
ex_ram_bank = 0;
last_ex_ram_bank_df = 0;
ex_ram_bank_df = 0;
write_only_pokey_at_4000 = false;
myCartInfo.cardtype = CT_NORMAL;
myCartInfo.region = NTSC;
myCartInfo.pokeyType = POKEY_NONE;
myCartInfo.hsc = false;
myCartInfo.cardctrl1 = 0;
myCartInfo.cardctrl2 = 0;
myCartInfo.hasHeader = false;
myCartInfo.dma_adjust = 0;
last_bank = 255;
last_ex_ram_bank = 0;
ex_ram_bank = 0;
last_ex_ram_bank_df = 0;
ex_ram_bank_df = 0;
write_only_pokey_at_4000 = false;
if (isDS_LITE) shadow_ram = ex_ram_bank ? (u8*)(ex_ram_buffer+0x0000) : (u8*)(ex_ram_buffer+0x4000); // for DS-Lite
else shadow_ram = ex_ram_bank ? (u8*)0x06830000 : (u8*)0x06834000; // // Only for the DSi.. see DS_LITE handling above
shadow_ram -= 0x4000; // Makes for faster indexing in Memory.c

View File

@ -29,14 +29,13 @@
Database_Entry myCartInfo __attribute__((section(".dtcm")));
extern uint cartridge_size;
Database_Entry game_list[] = {
{"f5150c0fc1948832211e57852abb0c6e", "Utility Cart", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=7800 Utility Cart
{"4332c24e4f3bc72e7fe1b77adf66c2b7", "3D Asteroids", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=3D Asteroids
{"0be996d25144966d5541c9eb4919b289", "Ace of Aces", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 12, 256, 220, 0}, // title=Ace Of Aces
{"877dcc97a775ed55081864b2dbf5f1e2", "Alien Brigade", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 7, 22, 264, 230, 1}, // title=Alien Brigade
{"d99bff88cd3cce191c26f5755842eb21", "Arkanoid", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"212ee2a6e66d8bb7fbf26f343cc8dc19", "Arkanoid", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"d99bff88cd3cce191c26f5755842eb21", "Arkanoid (ChunkyPixel Games)", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"212ee2a6e66d8bb7fbf26f343cc8dc19", "Arkanoid (ChunkyPixel Games)", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 0, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
{"89b8b3df46733e0c4d57aeb9bb245e6f", "Armor Attack II", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 12, 256, 220, 0}, // title=Armor Attack II
{"a65f79ad4a0bbdecd59d5f7eb3623fd7", "Asteroids Deluxe (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 230, 0}, // title=Asteroids Deluxe
{"07342c78619ba6ffcc61c10e907e3b50", "Asteroids", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 0, 0, 17, 256, 230, 0}, // title=Asteroids
@ -326,4 +325,4 @@ bool database_Load(byte *digest)
return true;
}
// End of file

View File

@ -232,9 +232,7 @@ void hash_Compute(const byte* source, uint length, byte * dest) {
for(index = 0; index < 16; index++) {
digest[index] = bufferptr[index];
}
//char buffer[33] = {0};
sprintf((char *)dest, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]);
//return buffer;
}

View File

@ -21,6 +21,18 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ----------------------------------------------------------------------------
// HighScore.cpp
//
// The HSC hardware uses the Toshiba TC5516APL chip which is 2048 x 8bit (2K)
// and is maintained by a battery CR2032 at 3V
//
// With an SRAM of this vintage, the contents of an uninitialized / freshly
// powered up chip would likely be random values. For emulation purposes, we
// are initializing the SRAM contents on a fresh board as if they were zeros.
//
// With this emulation, each game gets their own private 2K SRAM for the
// HSC memory. Further, to avoid problems with some games that do not initialize
// the SRAM, we are going to use a fresh snapshot of the full 2K of SRAM right
// after a known good cart (Asteroids - NTSC) has initialized the memory.
// ----------------------------------------------------------------------------
#include <fat.h>
#include <dirent.h>
@ -32,7 +44,6 @@
#define HS_SRAM_START 0x1000 // The 7800 RAM memory location of the high score cartridge SRAM
#define HS_SRAM_SIZE 2048 // The size of the high score cartridge SRAM and gets loaded at 7800 memory address 0x1000
#define HSC_CART_ROM_SIZE 4096 // The highscore.rom is exactly 4K in size and gets loaded at 7800 memory address 0x3000
#define HSC_TITLE_SIZE 33 // Includes 32 chars for title name and 1 char for size (strlen)
static byte high_score_sram[HS_SRAM_SIZE]; // Buffer for the actual 2K of HSC data
static byte high_score_rom[HSC_CART_ROM_SIZE]; // Buffer for the 4K of high score ROM (highscore.rom)
@ -41,7 +52,7 @@ byte high_score_cart_loaded = false; // Flips to true if the High Sco
// -----------------------------------------------------------------------------------------------------
// This is a snapshot of an initialized HSC after Asteroids (NTSC) initialized it with the name "HSC"
// A few of the modern homebrews don't do a good job of initializing the HSC and so we use this as
// as default starting SRAM which is squeaky clean and ready for use by the game.
// as default starting SRAM (of 0x00 before init) which is squeaky clean and ready for use by the game.
// -----------------------------------------------------------------------------------------------------
unsigned char A7800DS_00_sram[HS_SRAM_SIZE] = {
0x00, 0x00, 0x68, 0x83, 0xaa, 0x55, 0x9c, 0x02, 0x07, 0x12, 0x02, 0x1f, 0x00, 0x00, 0x00, 0x00,
@ -255,7 +266,7 @@ static bool cartridge_LoadHighScoreSram(void)
memory_Write(HS_SRAM_START + i, high_score_sram[i]);
}
return true; // We at least made the attempt to write out the .hsc save file
return true; // HSC SRAM is ready to go!
}
/*
@ -285,7 +296,7 @@ bool cartridge_LoadHighScoreCart(void)
}
high_score_cart_loaded = true;
// Now read in the associated .hsc SRAM file
// Now read in the associated .hsc SRAM file (or set SRAM to defaults)
cartridge_LoadHighScoreSram();
}
else

View File

@ -1,5 +1,4 @@
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ___ ___ ___ ___ ___ ____ ___ _ _
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator

View File

@ -20,7 +20,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// ----------------------------------------------------------------------------
// Region.h
// Region.c
// ----------------------------------------------------------------------------
#include "Region.h"
#include "Database.h"

View File

@ -24,17 +24,17 @@
// ----------------------------------------------------------------------------
#include "Riot.h"
uint riot_and_wsync __attribute__((section(".dtcm"))) = 0x00;
int riot_timer __attribute__((section(".dtcm"))) = TIM64T;
int riot_intervals __attribute__((section(".dtcm")));
uint riot_and_wsync __attribute__((section(".dtcm"))) = 0x00;
int riot_timer __attribute__((section(".dtcm"))) = TIM64T;
int riot_intervals __attribute__((section(".dtcm"))) = 0;
byte riot_dra __attribute__((section(".dtcm"))) = 0;
byte riot_drb __attribute__((section(".dtcm"))) = 0;
byte riot_dra __attribute__((section(".dtcm"))) = 0;
byte riot_drb __attribute__((section(".dtcm"))) = 0;
uint riot_elapsed __attribute__((section(".dtcm")));
int riot_currentTime __attribute__((section(".dtcm")));
uint riot_clocks __attribute__((section(".dtcm")));
uint riot_shift __attribute__((section(".dtcm")))=0;
uint riot_elapsed __attribute__((section(".dtcm"))) = 0;
int riot_currentTime __attribute__((section(".dtcm"))) = 0;
uint riot_clocks __attribute__((section(".dtcm"))) = 0;
uint riot_shift __attribute__((section(".dtcm"))) = 0;
void riot_Reset(void) {
riot_SetDRA(0);

View File

@ -2037,3 +2037,4 @@ next_inst:
}
}
// End of file

View File

@ -7,6 +7,22 @@
// Alekmaul (original port) and Greg Stanton (ProSystem Emulator) are thanked profusely.
//
// A7800DS emulator is offered as-is, without any warranty.
//
// The original GPL license:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// =====================================================================================
#include <stdio.h>
#include <fat.h>

View File

@ -1,3 +1,29 @@
// =====================================================================================
// Copyright (c) 2022-2024 Dave Bernazzani (wavemotion-dave)
//
// Copying and distribution of this emulator, it's source code and associated
// readme files, with or without modification, are permitted in any medium without
// royalty provided this copyright notice is used and wavemotion-dave (Phoenix-Edition),
// Alekmaul (original port) and Greg Stanton (ProSystem Emulator) are thanked profusely.
//
// A7800DS emulator is offered as-is, without any warranty.
//
// The original GPL license:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// =====================================================================================
#ifndef _MAIN_H
#define _MAIN_H