Compare commits
176 commits
Author | SHA1 | Date | |
---|---|---|---|
|
d57a21997a | ||
|
849c18eb2b | ||
|
c1d61673a7 | ||
|
ec31048360 | ||
|
08a5ed111b | ||
|
941f3c6302 | ||
|
1043fbc291 | ||
|
07057b5051 | ||
|
81fedf5a06 | ||
|
7ee7f113e3 | ||
|
a8f7c879f4 | ||
|
30d892e564 | ||
|
a2bb1219de | ||
|
4761ace958 | ||
|
fb3e058e2b | ||
|
92ac5d7a20 | ||
|
b80e0211f2 | ||
|
5510d23ae1 | ||
|
3f67763fd9 | ||
|
19ec089aa9 | ||
|
e452594769 | ||
|
b3a96e11ea | ||
|
f116ec6863 | ||
|
13d89fe935 | ||
|
ef779ea625 | ||
|
c08f1b5329 | ||
|
66d344522b | ||
|
287894babc | ||
|
4ff31b149c | ||
|
f1540e71a9 | ||
|
a57f6293c8 | ||
|
e07035aa31 | ||
|
c1e90fdb59 | ||
|
8fe0219f2c | ||
|
7a5fdc4db2 | ||
|
44c7432e6e | ||
|
90abe106ce | ||
|
30f0a004c0 | ||
|
07887cc610 | ||
|
7441d9ff2a | ||
|
0b705b495c | ||
|
a6f3527016 | ||
|
455e2d24f3 | ||
|
4abfabf98f | ||
|
b172b7d8b5 | ||
|
5907e921ba | ||
|
653e4354ea | ||
|
47bcbdf7e9 | ||
|
11e0eb748c | ||
|
6b15e128e5 | ||
|
29bde658bc | ||
|
7b9aa7fcf0 | ||
|
1a8f11f129 | ||
|
f7c4c647ee | ||
|
700453df0d | ||
|
e739276662 | ||
|
eb2f263cd2 | ||
|
aa02a71247 | ||
|
eb91c9c37a | ||
|
a3c6f26fa3 | ||
|
009c4d2c4d | ||
|
6bcca8c203 | ||
|
be39c6110b | ||
|
53c4e85496 | ||
|
81a7851cd9 | ||
|
e955ae60d3 | ||
|
213a453af1 | ||
|
4843c9d9e4 | ||
|
4620f70ed0 | ||
|
bb9bd32e89 | ||
|
7c0e11c299 | ||
|
97d494e265 | ||
|
b4250c785f | ||
|
c48a14ba79 | ||
|
ef4a1b62c5 | ||
|
1673fa8bda | ||
|
8fe429c2d4 | ||
|
17d476de09 | ||
|
d7f36f755e | ||
|
1e435318bd | ||
|
ef9d3f03b8 | ||
|
d23d03d00c | ||
|
973c07ec38 | ||
|
17f4f468cb | ||
|
a05e9519e5 | ||
|
6cd4ed6cd2 | ||
|
73c1c123b1 | ||
|
42452d0973 | ||
|
c3533d842e | ||
|
9be397cbb3 | ||
|
39412a3b57 | ||
|
78bf4c0672 | ||
|
e6dbfe966d | ||
|
f6234abc87 | ||
|
76beb61caa | ||
|
035becf824 | ||
|
2a505dd775 | ||
|
8f21c6e20f | ||
|
d047cca163 | ||
|
4394684276 | ||
|
d0c5361318 | ||
|
8255ce6b8f | ||
|
9ab2be040f | ||
|
52e2602541 | ||
|
5a18a0d4a6 | ||
|
e05339a4b8 | ||
|
c74cf87a3a | ||
|
5c52539582 | ||
|
0c5fa25c0c | ||
|
c9c0139d7a | ||
|
716a765520 | ||
|
a0476b47a9 | ||
|
f9e3c651d3 | ||
|
851d7a2ac8 | ||
|
e688e50596 | ||
|
f4f0c86639 | ||
|
b8388f6647 | ||
|
62f1924125 | ||
|
3fceae1a2f | ||
|
1f3d77e4c7 | ||
|
47ba03500f | ||
|
6650562579 | ||
|
6d6042b9b5 | ||
|
921647e330 | ||
|
eea94bc158 | ||
|
a945ffe36d | ||
|
d1b274b96d | ||
|
d1b5f97003 | ||
|
2654197ce8 | ||
|
3e799c569a | ||
|
5c8a17939e | ||
|
e2f3d2a715 | ||
|
02b5a213f3 | ||
|
b2e6b2b024 | ||
|
eb5cd0a14f | ||
|
b5b4e03017 | ||
|
e8c05b4e94 | ||
|
cf6684e73e | ||
|
38d24d4458 | ||
|
8229ced2c8 | ||
|
9b52a757b9 | ||
|
e3485a5c52 | ||
|
3fa45f80f7 | ||
|
eaf09f13ba | ||
|
3a36e21ff1 | ||
|
f7a2384d6e | ||
|
b4b0dd416f | ||
|
533dd36348 | ||
|
ff9a63f047 | ||
|
4756093a0d | ||
|
5d1257c755 | ||
|
13bf29a600 | ||
|
ada69f4947 | ||
|
0f6dcd81ca | ||
|
a8326ba44f | ||
|
e62d0b68e7 | ||
|
3e7bb95655 | ||
|
705e524f0b | ||
|
31ceb70d2a | ||
|
48f625a80f | ||
|
2f8b6ea5c3 | ||
|
d06d768344 | ||
|
ede76f6ae3 | ||
|
43daea1fdd | ||
|
d47f3d9037 | ||
|
7e0108a84b | ||
|
639544adf8 | ||
|
3f0b07d305 | ||
|
317c5da4f8 | ||
|
c13ad22e95 | ||
|
d568079b58 | ||
|
38bcf38fea | ||
|
bc1b557f47 | ||
|
02cfa1cc04 | ||
|
bd51642b31 | ||
|
6901a5f5a6 |
BIN
A7800DS-LITE.nds
BIN
A7800DS.nds
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=2.6
|
||||
VERSION=5.1
|
||||
TARGNAME=A7800DS
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
|
432
README.md
Normal file
|
@ -0,0 +1,432 @@
|
|||
# a7800DS
|
||||
|
||||
a7800DS is an Atari ProSystem 7800 console emulator for the DS/DSi.
|
||||
|
||||
To use this emulator, you must use compatible roms with a78/bin format.
|
||||
Strongly recommend you use NTSC roms... PAL ones have more scanlines and will render
|
||||
more slowly and since the sound core is tied to scanlines, the sound will be wrong.
|
||||
All the debug on this port to the DS has been done with NTSC roms - seek them out!
|
||||
Do not ask me about such files, I only supply the emulator. A search with Google will certainly
|
||||
help you. The emulator was developed using Trebor's "7800 ProPack" of well-curated games.
|
||||
The emulator will auto-start in /roms/a7800 or /roms/a78 if those directories exist.
|
||||
|
||||
Features :
|
||||
----------
|
||||
Most things you should expect from an emulator. Speed is excellent on the DSi and
|
||||
a little less great on the older DS-LITE. For the DS-LITE you can expect full speed on
|
||||
a very large chunk of the 7800 library. The more traditional games (think: Asteroids,
|
||||
Astro Blaster, Robotron, Food Fight, Centipede, Pac-Man Collection, etc) will
|
||||
all run great. The really big bankswitched games may struggle on the older
|
||||
DS-LITE/PHAT hardware - try the game and see!
|
||||
|
||||
The emulator will support ROMs up to 1024K (1MB!) in size + the 128 byte .a78 header.
|
||||
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.
|
||||
|
||||
The 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!
|
||||
|
||||
If you want to use a real Atari 7800 BIOS, find yourself the 4K version and place it
|
||||
into the same directory as mentioned in the paragraph above.
|
||||
|
||||
Copyright :
|
||||
----------
|
||||
A7800DS is Copyright 2021-2025 by Dave Bernazzani (wavemotion-dave).
|
||||
|
||||
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 :
|
||||
----------
|
||||
For this particular emulator, we use ProSystem as the base. That's always been a bit
|
||||
problematic in terms of accuracy - often resulting in small graphical glitches and
|
||||
other artifacts on screen. However, in the past year I've worked out many of those
|
||||
issues and most of the games look, sound and play great now. However, do not expect
|
||||
perfect emulation - if you're looking for a highly accurate emulator for the 7800
|
||||
ProSystem, this isn't it - try A7800 or JS7800 instead. But if you're looking to enjoy
|
||||
some classic 7800 console goodness on your DS/DSi then you've come to the right place!
|
||||
|
||||
Known Issues and Limitations:
|
||||
----------
|
||||
- Lightgun is not supported.
|
||||
- Paddles are not supported.
|
||||
- PAL is not supported - use NTSC instead.
|
||||
- Souper mapper (Ricky & Vicky) is not supported.
|
||||
- Keystone Koppers and ARTI have slight sound issues as Pokey emulation is not perfect.
|
||||
- Only one Pokey is supported at 4000h, 800h or 450h (no Dual Pokey).
|
||||
- XM is not supported (beyond HSC and Pokey).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
How to use a7800DS :
|
||||
--------------------------------------------------------------------------------
|
||||
Place .NDS on your SD card and launch with Twilight Menu++ or Unlaunch.
|
||||
If you want to run on a flash cart place it as you would any homebrew pretty
|
||||
much anywhere on your flashcart SD card.
|
||||
|
||||
If you want to use a real Atari 7800 BIOS, find yourself the 4K version and place
|
||||
this file named exactly 7800.rom in the /roms/bios directory (alternate locations
|
||||
are /data/bios or you can place it in the same directory as the emulator).
|
||||
|
||||
When the emulator starts, click on the cartridge slot to choose a file. Use Up/Down
|
||||
to select a file, then use A to load it.
|
||||
|
||||
Controls :
|
||||
* Direction pad : the joystick ...
|
||||
* A : Fire button 1
|
||||
* B : Fire button 2
|
||||
* SELECT : SELECT Button
|
||||
* START : PAUSE Button
|
||||
* X : Configurable (default: Pan Screen Down)
|
||||
* Y : Configurable (default: Pan Screen Up)
|
||||
* L/R + DPAD : Used to Shift Offsets and Scale Screen to desired ratio
|
||||
* L + R + X : Hold for 1 second to swap LCD screens top/bottom
|
||||
|
||||
Use stylus on buttons for other actions on bottom screen.
|
||||
|
||||
The new SNES2Atari adaptor is supported as a controller type for the few new games
|
||||
that utilize it. This allows all of the DS buttons to map into the game - exactly
|
||||
as labeled (D-Pad plus ABXY, Left Shoulder, Right Shoulder and Start, Select).
|
||||
|
||||
High Score Saving works if you have highscore.rom (exact name) in your
|
||||
roms directory where you load your games... The .hsc backing file will be written
|
||||
automatically as the game runs. Only games programmed to use the highscore cart
|
||||
will save scores.
|
||||
|
||||
Configuration :
|
||||
----------
|
||||
Generally you would use this to select a bankswitching scheme if the proper type wasn't auto-detected.
|
||||
The following schemes are supported:
|
||||
|
||||
* NORMAL Anything 48K or less... fits into memory (0xffff downwards) without switching.
|
||||
* SUPERCART Games that are 128+K in size with nothing mapped in at 0x4000
|
||||
* SUPERCART_LARGE Games that are 144+K in size with the extra 16K bank 0 fixed at 0x4000
|
||||
* SUPERCART_RAM Games that are 128+K in size with extra 16K of RAM at 0x4000
|
||||
* SUPERCART_ROM Games that are 128+K in size with bank 6 fixed at 0x4000
|
||||
* SUPERCART_RAMX2 Games that are 128+K in size with extra 32K of RAM at 0x4000 (bankswitched in 16K chunks)
|
||||
* FLAT WITH RAM Games that are 16K or 32K in size and utilize 16K of RAM at 0x4000
|
||||
* BANKSETS Games that use the new Banksets handling (2x32, 2x48, 2x52, 2x128, 2x256 and 2x512 supported).
|
||||
* BANKSETS RAM Games that use the new Banksets handling with 16K of RAM at 0x4000 (same RAM for Maria and Sally).
|
||||
* BANKSETS HALT RAM Games that use the new Banksets handling with 16K of RAM at 0x4000 (Maria and Sally see different 16K RAM).
|
||||
* ACTIVISION Mostly for Double Dragon and Rampage by Activision
|
||||
* ABSOLETE Only for the F-18 Hornet game by Absolete Entertainment
|
||||
* FRACTALUS Only for the Rescue on Fractalus prototype (not a complete game but neat to see). This is EXRAM/A8.
|
||||
|
||||
Frame Skipping can be OFF (show all frames), Moderate (Show 3/4 frames) or Agressive (only show 1/2 frames). The latter is
|
||||
only really needed for the DS-Lite/Phat where the faster DSi CPU isn't available.
|
||||
|
||||
Press START to save off your configuration - if you made changes you should re-load the game to ensure all settings are applied.
|
||||
|
||||
Of Mice, Men and Screen Resolutions :
|
||||
----------
|
||||
The DS/DSi has a native screen resolution of 256x192. This is not ideal for the Atari 7800 where many of the games are 320
|
||||
pixels across and often more than 192 scanlines. The original Atari NTSC spec called for 192 vertical scanlines and a few
|
||||
of the early games (Asteroids, Ms. Pac-Man, etc.) did stick to that but most later games utilize more vertical scanlines.
|
||||
A typical NTSC TV can handle 230+ scanlines fairly well and so many of the Atari 7800 games utilize some number of extra
|
||||
scanlines to pack as much awesome gameplay as possible onto the screen.
|
||||
|
||||
This is a problem for our hero, the DS/DSi. Fortunately the DS has the ability to scale/stretch as needed. But when doing
|
||||
so, there will be missing scanlines. For example, if the game utilizes 200 scalines but the DS can only show 192, there are
|
||||
8 scanlines that must go missing... if scaled down to 192 pixels to fit the screen, these extra scalines might be in the
|
||||
middle of the playfield which is not great. If you scale the screen up (using Configuration options or the L/R shoulder
|
||||
buttons in conjunction with the D-PAD to shift/scale the sceren), then some of the pixels (left or right, up or down) will
|
||||
be cropped off the screen. This might not be a big deal - sometimes the very top and bottom of a game are just clouds or
|
||||
ground that can be safely cropped without any loss in gameplay. For many games, the top 16 pixels are the score / lives
|
||||
remaining.
|
||||
|
||||
Most games have scaling defaults that look good enough. Some games will cut off a few pixel lines at the top and bottom - but
|
||||
they will still be perfectly playalbe. However there are some thigns you can (and should!) do to help.
|
||||
|
||||
Recent versions of the emulator have a magnifying glass icon that will zoom and center the display to 1:1 of the actual 7800 output.
|
||||
This will crop some pixels off the sides and top/bottom but is useful to temporarily zoom up to enter things like high scores
|
||||
where the text may be hard to read when shrunk down.
|
||||
|
||||
More importantly, you can utilize the X and Y buttons as a pan down/up. This is massively useful for games that have a score at
|
||||
the top of the display (Galaxian, Space Invaders, Popeye, bonQ, etc). Here you can stretch up the screen in the Y direction so
|
||||
that it is nearly 1:1 and shift the score off the top of the screen. Then, during gameplay, you can tap the X button to temporarily
|
||||
pan the display down so the score comes into view briefly... and it will magically shift back up after a half second. You can do
|
||||
this while you are playing - usually when you lose a life you can tap the X button to quickly glace at your score. This gives
|
||||
more useable scanlines for actual gameplay. Think of this like you're at the arcade and you have to glance up to see your
|
||||
score when focused on the field of play. It takes a little getting used to but this mechanism really helps map the more complicated
|
||||
game graphics onto the small sceren. Of course youc an always scale the screen down to it's totally visible - but there will be
|
||||
some loss of scanline information. Experiment and determine what works best for you. Many of the popular games already have
|
||||
the screen set to perfectly pan up/down to bring in the score/status while leaving the playfield as close to 1:1 as possible.
|
||||
|
||||
And remember - once you get your screen settings the way you want, be sure to go into the GEAR icon and hit START to save out
|
||||
your current configuration (which includes your screen offset/scaling tweaks on a per-game basis).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
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 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 and timing issues.
|
||||
* The MAXMOD audio library is Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org). See https://github.com/devkitPro/maxmod
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Original Author:
|
||||
Alekmaul
|
||||
alekmaul@portabledev.com
|
||||
http://www.portabledev.com
|
||||
|
||||
Updates by wavemotion-dave: https://github.com/wavemotion-dave/A7800DS
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
History :
|
||||
--------------------------------------------------------------------------------
|
||||
V5.1 : 27-Feb-2025 by wavemotion-dave
|
||||
* 7800 BIOS is now supported. Place bios exactly named '7800.rom' in /roms/bios, /data/bios or same directory as the emulator itself.
|
||||
* New internal database with many cleanups and corrections. Now compliant with Trebor Pro-Pack v8_16 from early 2025.
|
||||
* New configuration option to allow mapping both both X and Y buttons.
|
||||
* Maria and CPU cycle counting are much closer to real hardware - all of the DMA Cycle adjustments/hacks have been removed.
|
||||
* This fixes a number of small problems such as Pole Position II joystick selection of track when game loads.
|
||||
|
||||
V5.0 : 21-Feb-2025 by wavemotion-dave
|
||||
* Kangaroo mode fixed and fully implemented. Cleans up some small graphical glitches on a number of games.
|
||||
* Composite Artifacting implemented for Tower Toppler and Jinks.
|
||||
* Sound handler fixed so that drop-outs of sounds are eliminated (or at least greatly minimized).
|
||||
* The X button on the NDS is now configurable to a range of joystick/console buttons.
|
||||
|
||||
V4.9 : 17-Feb-2025 by wavemotion-dave
|
||||
* High Score (HSC) auto-save improvements - no longer write the backing .hsc file if the write didn't actually change HSC data.
|
||||
* Improved Sally emulation accuracy and optimization pass to render the games 3-4% faster.
|
||||
* Improved Pokey emulation - missing sounds on games like Ballblazer are now much better.
|
||||
* Improved memory emulation for more accurate mirror handling - 7800 Utility cart now shows this as a PASS.
|
||||
* Improved memory caching to help with the really big games (those 512K or larger).
|
||||
* All but two games on the DSi are now rendered without any form of frameskip. Older DS-Lite/Phat reduces frameskip due to new optimizations.
|
||||
|
||||
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
|
||||
* 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)
|
||||
* Internal database tweaks for the latest homebrews and ports.
|
||||
* Other minor tweaks and improvements as time permitted.
|
||||
|
||||
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.
|
||||
* Support for .a78 V4 headers (will fall back to V3 if not available)
|
||||
|
||||
V4.5 : 18-Nov-2022 by wavemotion-dave
|
||||
* SNES2Atari adaptor supported.
|
||||
* Improved display output to smooth over the fonts a bit.
|
||||
* Small tweaks to internal database to ensure everything looks as good as possible.
|
||||
|
||||
V4.4 : 14-Nov-2022 by wavemotion-dave
|
||||
* New palette options from the Trebor 'Pro Pack' of colors. COOL, WARM (default), and HOT allow you to shift the color temperature slightly on a per-game basis.
|
||||
* Improved sound channel mixing so as not to halve the volume when mixing POKEY + TIA.
|
||||
|
||||
V4.3 : 11-Nov-2022 by wavemotion-dave
|
||||
* Full support for the new Banksets scheme including the upcoming Attack of the Petscii Robots game!
|
||||
* Added the stable "illegal" opcode support for the 6502 CPU to ensure all games run properly.
|
||||
* New Maria cycle handling is more accurate than it's been in any previous version. More games run closer to perfect.
|
||||
* Improved rendering and a bit more optmization to make almost every game playable on the older DS-Lite.
|
||||
|
||||
V4.2 : 06-Nov-2022 by wavemotion-dave
|
||||
* Added support for bankswitched RAM (32K of RAM swiched in 16K chunks). This makes the Ex version of 1942 playable.
|
||||
* Added alternate way of handling bankswitched RAM the same way as the DragonFly cart or SN board: via writes to 0xFFFF.
|
||||
* Fix graphical glitch for Ballblazer (just hiding it off screen).
|
||||
* Numerous small updates to the internal cart database to ensure game run with the proper settings (mostly High Scores)
|
||||
* New 8x density on the High Score Cart - transparent to the user but provides more slots so the HSC won't fill up.
|
||||
* Flat 32K plus RAM cart type supported.
|
||||
* Pokey @800 supported for upcoming homebrews.
|
||||
|
||||
V4.1 : 02-Nov-2022 by wavemotion-dave
|
||||
* Overhaul Maria cycle stealing - all games now use the proper cycle stealing with much closer to accurate timing. This fixes games like One-on-One and Kung Fu Master.
|
||||
* Other minor cleanups and tweaks as time permitted.
|
||||
|
||||
V4.0 : 01-Nov-2022 by wavemotion-dave
|
||||
* Overhaul the audio system to use the MAXMOD streaming library to eliminate sound 'zingers'
|
||||
* Other minor cleanup and tweaks as time permitted.
|
||||
|
||||
V3.9 : 29-Oct-2022 by wavemotion-dave
|
||||
* More optmization and more games playable on the DS-Lite.
|
||||
* Highscore A7800.SRAM file moved to /data (move yours manually) - this allows the same high score file even if your roms are in different directories.
|
||||
* Fix for One-on-One.
|
||||
* Fix for voices in Jinx.
|
||||
* Cleanup of code - removed unused functions and vars. Switched to a memory-lite sprintf().
|
||||
|
||||
V3.8 : 26-Oct-2022 by wavemotion-dave
|
||||
* Massive optmization of the Maria rendering to help the DS-Lite run more games.
|
||||
* Fix for Rampage
|
||||
* Fix for Rescue on Fractalus
|
||||
* Fix for F-18 Hornet
|
||||
* Fix for Double Dragon
|
||||
* Fix for Basketbrawl
|
||||
* Better A78 header parsing for improved game detection
|
||||
* New Moderate Frameskip to show 3/4 frames (not as aggressive as the old 1/2 frameskip)
|
||||
* Support for 1024K (+128 byte header) games. Only a few tech demos available so far.
|
||||
* Removed most of the old hacks for DS-Lite as the speed is good enough to render those games properly.
|
||||
|
||||
V3.7 : 23-Oct-2022 by wavemotion-dave
|
||||
* Optmization across the board for faster and smoother performance.
|
||||
* Gained enough speed that we have restored full HQ sound for the DS-Lite.
|
||||
* bonQ fixed graphical glitches.
|
||||
* Keystone Koppers fixed graphical glitches.
|
||||
* Latest homebrews added to the internal database.
|
||||
* New configuration menu so you can tweak settings - new homebrews won't need a new A7800DS.
|
||||
* Better A78 v3 header support so more games run right.
|
||||
|
||||
V3.6 : 04-Jun-2022 by wavemotion-dave
|
||||
* Fix for XM detection so the newest Pac-Man Collection (PMC-XM) works!
|
||||
* Minor database cleanups so all the more recent games run.
|
||||
|
||||
V3.5 : 12-Feb-2022 by wavemotion-dave
|
||||
* Across the board cleanup of code. Copyright notice added.
|
||||
* Fixed High-Score save on Time Salvo
|
||||
* Slight memory optmization for reduced memory footprint.
|
||||
|
||||
V3.4 : 6-Feb-2022 by wavemotion-dave
|
||||
* Frameskip rendering improved by more than 10% - making more DS-LITE games playable!
|
||||
* Minor improvements to touch-screen key handling and other code cleanups.
|
||||
|
||||
V3.3 : 4-Feb-2022 by wavemotion-dave
|
||||
* Squeezed out another frame of performance.
|
||||
* Super Skateboardin' graphics fixed.
|
||||
* DSi eliminates frameskip on 80% of the library.
|
||||
* Updated 50 entries in the internal database - more new homebrews run.
|
||||
|
||||
V3.2 : 1-Feb-2022 by wavemotion-dave
|
||||
* A 5-8% speedup across the board through a number of small optimizations in core areas.
|
||||
|
||||
V3.1 : 31-Jan-2022 by wavemotion-dave
|
||||
* Now using more VRAM for bank swapping and partial DMA transfer to speed up large games.
|
||||
* Reverted part of the sound core to improve sound quality.
|
||||
* File selection cleanups to scroll less fast and be generally easier to see.
|
||||
|
||||
V3.0 : 06-Nov-2021 by wavemotion-dave
|
||||
* Reworked sound output core so it's now zinger-free!
|
||||
* Refresh of bottom screen - improved font and button debounce.
|
||||
|
||||
V2.9 : 03-Nov-2021 by wavemotion-dave
|
||||
* Fixed loading of large SUPER CART roms.
|
||||
|
||||
V2.8 : 02-Nov-2021 by wavemotion-dave
|
||||
* A bit of speed - enough to eliminate the old DS-LITE version.
|
||||
* A few new homebrews added to the internal database.
|
||||
* Optmized sound buffers for (very) slightly better performance.
|
||||
* highscore.rom can now bin in /roms/bios or /data/bios
|
||||
* Cleanup code as time permitted.
|
||||
|
||||
V2.7 : 02-Apr-2021 by wavemotion-dave
|
||||
* New support for the latest homebrews: Galaxian final
|
||||
* Added ability to swap screens using L+R+A
|
||||
|
||||
V2.6 : 02-Apr-2021 by wavemotion-dave
|
||||
* Faster directory/file listing.
|
||||
* Support for the latest homebrews: Galaxian and Popeye
|
||||
* Improved scaling and offset handling using L/R + Arrow Keys to match other emulators.
|
||||
|
||||
V2.5 : 15-Jan-2021 by wavemotion-dave
|
||||
* Added .A78 header naming search and as a backup filename search to help
|
||||
properly identify the game being loaded so that the right settings can be applied.
|
||||
|
||||
V2.4 : 8-Jan-2021 by wavemotion-dave
|
||||
* Improvement in bank switching allowing most games to run 60FPS.
|
||||
|
||||
V2.3 : 6-Jan-2021 by wavemotion-dave
|
||||
* Fixed large cart support so 512kb games run fine.
|
||||
* Fixed voice in Frenzy/Berzerk.
|
||||
* Fixed graphical glitches in Alien Brigade.
|
||||
* Optmized bank switching so more big games run smoothly.
|
||||
* Added default difficulty switches for the few games that need them.
|
||||
* Lots of cleanups as time permitted.
|
||||
|
||||
V2.2 : 5-Jan-2021 by wavemotion-dave
|
||||
* More memory tweaks - faster processing of memory for another 5% speedup.
|
||||
|
||||
V2.1 : 3-Jan-2021 by wavemotion-dave
|
||||
* Now using DTCM and VRAM for some key memory areas to speed up the emulator almost 10%
|
||||
|
||||
V2.0 : 1-Jan-2021 by wavemotion-dave
|
||||
* Pokey and TIA sound core reworked to provide sound that is worth listening to.
|
||||
* Please run on a DSi, DSi-XL/LL or 3DS. You won't be happy with the performance on a DS-LITE/PHAT.
|
||||
|
||||
V1.9 : 31-Dec-2020 by wavemotion-dave
|
||||
* Robotron now works with with Twin-Sticks!
|
||||
* Minor cleanup and polish to end the year...
|
||||
|
||||
V1.8 : 23-Dec-2020 by wavemotion-dave
|
||||
* Major improvements to CPU core to get about 10% speed boost across the board.
|
||||
More games playable at full speed on DSi and above. Special DS-LITE build
|
||||
included that supports only the smallest and most basic games (but at near
|
||||
full speed).
|
||||
|
||||
V1.7a : 21-Dec-2020 by wavemotion-dave
|
||||
* Full Pokey Support at both 450 and 4000. XM RAM mapping at 4000 so games
|
||||
like Serpentine will run properly now. Undocumented opcodes for the Sally
|
||||
processor now implemented so games like Popeye will run fine.
|
||||
|
||||
V1.7 : 20-Dec-2020 by wavemotion-dave
|
||||
* After much thought and debug, I've ditched Kangaroo mode. As near as I can
|
||||
tell it's used on only a couple of games and not for gameplay - and it costs
|
||||
more DS-CPU time than it's worth. There is no harm other than a potential
|
||||
graphical glitch which I've not noticed and that CPU time is precious.
|
||||
|
||||
V1.6b : 19-Dec-2020 by wavemotion-dave
|
||||
* Fixed bug causing black rectangles on some games - thanks to Wii-7800!
|
||||
|
||||
V1.6 : 17-Dec-2020 by wavemotion-dave
|
||||
* Minor cleanup. Rebranding to PHOENIX EDITION.
|
||||
|
||||
V1.5 : 15-Dec-2020 by wavemotion-dave
|
||||
* Overhaul of scaling and X/Y offsets so that more games look pixel perfect.
|
||||
* More homebrews run... compatibility table added to the back end of this doc.
|
||||
* More robust handling of High Score Cart and saving of files.
|
||||
|
||||
V1.4 : 13-Dec-2020 by wavemotion-dave
|
||||
* Implemented Hiscore Saving per the HSC cart. Put the 4k highscore.rom (don't ask)
|
||||
where your ROMs live. If found, it will enable saving of high scores
|
||||
on all 9 original games (Asteroids, Joust, Centipede, Xevious, Dig Dug, Galaga,
|
||||
Food Fight, Ms Pac-Man and Robotron) as well as most of the newer homebrews.
|
||||
|
||||
V1.3 : 12-Dec-2020 by wavemotion-dave
|
||||
* Backported some fixes and emulation timing improvments from Prosystem 1.3g
|
||||
plus the Wii version. Renders a few more games playable.
|
||||
* Fixed region for Froggie and Beef Drop - they now look right and play
|
||||
at full speed.
|
||||
* Minor other improvements as time permitted.
|
||||
|
||||
V1.2 : 10-Dec-2020 by wavemotion-dave
|
||||
* More speed improvements. Fixed some 320 pixel games. Improved sound.
|
||||
|
||||
V1.1 : 09-Dec-2020 by wavemotion-dave
|
||||
* Brought back to life... cleanup and about a 50% speed improvement, better
|
||||
screen rendering/scaling and slightly improved UI features.
|
||||
|
||||
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/
|
BIN
arm7/A7800DS.elf
|
@ -24,7 +24,7 @@ DATA :=
|
|||
#---------------------------------------------------------------------------------
|
||||
ARCH := -mthumb-interwork
|
||||
|
||||
CFLAGS := -g -Wall -O3\
|
||||
CFLAGS := -g -Wall -O2\
|
||||
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
|
||||
-ffast-math \
|
||||
$(ARCH)
|
||||
|
@ -36,8 +36,8 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fno-rtti
|
|||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,-Map,$(notdir $*).map
|
||||
|
||||
#LIBS := -ldswifi7 -lmm7 -lnds7
|
||||
LIBS := -ldswifi7 -lnds7
|
||||
#LIBS := -ldswifi7 -lmm7 -lnds7 -lmm7
|
||||
LIBS := -ldswifi7 -lnds7 -lmm7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
|
|
@ -9,7 +9,8 @@ typedef enum {
|
|||
} FifoMesType;
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void soundEmuDataHandler(int bytes, void *user_data) {
|
||||
void soundEmuDataHandler(int bytes, void *user_data)
|
||||
{
|
||||
int channel = -1;
|
||||
|
||||
FifoMessage msg;
|
||||
|
@ -40,7 +41,8 @@ void soundEmuCommandHandler(u32 command, void* userdata) {
|
|||
int data = command & 0xFFFF;
|
||||
int channel = (command >> 16) & 0xF;
|
||||
|
||||
switch(cmd) {
|
||||
switch(cmd)
|
||||
{
|
||||
|
||||
case SOUND_SET_VOLUME:
|
||||
SCHANNEL_CR(channel) &= ~0xFF;
|
||||
|
@ -75,7 +77,8 @@ void soundEmuCommandHandler(u32 command, void* userdata) {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void installSoundEmuFIFO(void) {
|
||||
void installSoundEmuFIFO(void)
|
||||
{
|
||||
fifoSetDatamsgHandler(FIFO_USER_01, soundEmuDataHandler, 0);
|
||||
fifoSetValue32Handler(FIFO_USER_01, soundEmuCommandHandler, 0);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <maxmod7.h>
|
||||
|
||||
extern void installSoundEmuFIFO(void);
|
||||
extern void mmInstall( int fifo_channel );
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void VblankHandler(void) {
|
||||
|
@ -54,9 +55,10 @@ void powerButtonCB() {
|
|||
exitflag = true;
|
||||
}
|
||||
|
||||
void mmInstall(int);
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
int main() {
|
||||
//---------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------
|
||||
readUserSettings();
|
||||
|
||||
|
@ -66,7 +68,7 @@ int main() {
|
|||
touchInit();
|
||||
fifoInit();
|
||||
|
||||
//mmInstall(FIFO_MAXMOD);
|
||||
mmInstall( FIFO_MAXMOD );
|
||||
|
||||
SetYtrigger(80);
|
||||
|
||||
|
@ -75,12 +77,10 @@ int main() {
|
|||
|
||||
installSystemFIFO();
|
||||
|
||||
installSoundEmuFIFO();
|
||||
|
||||
irqSet(IRQ_VCOUNT, VcountHandler);
|
||||
//irqSet(IRQ_VBLANK, VblankHandler);
|
||||
irqSet(IRQ_VBLANK, VblankHandler);
|
||||
|
||||
irqEnable( IRQ_VCOUNT | IRQ_NETWORK);
|
||||
irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK);
|
||||
|
||||
setPowerButtonCB(powerButtonCB);
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ include $(DEVKITARM)/ds_rules
|
|||
# DATA is a list of directories containing binary files
|
||||
# all directories are relative to this makefile
|
||||
#---------------------------------------------------------------------------------
|
||||
BUILD := build
|
||||
BUILD := build
|
||||
SOURCES := source/emu source
|
||||
INCLUDES := source/emu source include
|
||||
DATA := data
|
||||
DATA := data
|
||||
GRAPHICS := gfx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
@ -26,22 +26,19 @@ GRAPHICS := gfx
|
|||
#ARCH := -mthumb -mthumb-interwork
|
||||
ARCH :=
|
||||
|
||||
#CFLAGS := -g -Wall -O2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math $(ARCH)
|
||||
CFLAGS := -Wall -Ofast -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math -fsigned-char $(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM9
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
|
||||
#ASFLAGS := -g $(ARCH) -march=armv5te -mtune=arm946e-s
|
||||
ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s
|
||||
ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s
|
||||
|
||||
#LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
LDFLAGS = -specs=ds_arm9.specs $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
LDFLAGS = -specs=ds_arm9.specs $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lfat -lnds9
|
||||
LIBS := -lfat -lnds9 -lmm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
@ -56,7 +53,7 @@ LIBDIRS := $(LIBNDS)
|
|||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export ARM9ELF := $(CURDIR)/$(TARGET).elf
|
||||
export ARM9ELF := $(CURDIR)/$(TARGET).elf
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
|
@ -123,13 +120,8 @@ $(ARM9ELF) : $(OFILES)
|
|||
@$(bin2o)
|
||||
|
||||
%.s %.h : %.png
|
||||
# grit $< -fts -W3 -gT! -gzl -gB16 -gb -o$*
|
||||
grit $^ -o $@ -gt -mrt -mR8 -mLs -gzl -mzl
|
||||
|
||||
#%.gif.o : %.gif
|
||||
# @echo $(notdir $<)
|
||||
# @$(bin2o)
|
||||
|
||||
%.wav.o : %.wav
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
|
BIN
arm9/data/keyclick.wav
Normal file
BIN
arm9/data/soundbank.bin
Normal file
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 13 KiB |
|
@ -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
|
||||
|
||||
|
@ -7,7 +33,7 @@
|
|||
#define A7800_PLAYGAME 0x04
|
||||
#define A7800_QUITSTDS 0x05
|
||||
|
||||
extern int etatEmu;
|
||||
extern short int emu_state;
|
||||
|
||||
typedef enum {
|
||||
EMUARM7_INIT_SND = 0x123C,
|
||||
|
@ -17,8 +43,7 @@ typedef enum {
|
|||
|
||||
typedef struct FICtoLoad {
|
||||
char filename[255];
|
||||
bool directory;
|
||||
unsigned int uCrc;
|
||||
u8 directory;
|
||||
} FICA7800;
|
||||
|
||||
typedef struct {
|
||||
|
@ -32,20 +57,14 @@ typedef struct {
|
|||
|
||||
extern gamecfg GameConf;
|
||||
|
||||
extern uint video_height; // Actual video height
|
||||
extern unsigned short *bufVideo; // Video buffer
|
||||
|
||||
|
||||
extern void FadeToColor(unsigned char ucSens, unsigned short ucBG, unsigned char ucScr, unsigned char valEnd, unsigned char uWait);
|
||||
|
||||
extern unsigned long crc32 (unsigned int crc, const unsigned char *buf, unsigned int len);
|
||||
|
||||
extern void vblankIntr();
|
||||
|
||||
extern void dsInitScreenMain(void);
|
||||
extern void dsInitTimer(void);
|
||||
extern void dsShowScreenEmu(void);
|
||||
extern void dsShowScreenMain(void);
|
||||
extern void dsShowScreenMain(bool);
|
||||
extern void dsFreeEmu(void);
|
||||
extern void VsoundHandler(void);
|
||||
extern void dsLoadGame(char *filename);
|
||||
|
|
389
arm9/source/config.c
Normal file
|
@ -0,0 +1,389 @@
|
|||
// =====================================================================================
|
||||
// Copyright (c) 2022-2025 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.
|
||||
// =====================================================================================
|
||||
#include <nds.h>
|
||||
#include <stdio.h>
|
||||
#include <fat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
#include "Region.h"
|
||||
#include "bgBottom.h"
|
||||
#include "bgFileSel.h"
|
||||
#include "printf.h"
|
||||
|
||||
struct AllConfig_t allConfigs;
|
||||
|
||||
extern int bg0, bg0b, bg1b;
|
||||
|
||||
static int display_options_list(bool bFullDisplay);
|
||||
|
||||
#define CONFIG_INSTRUCTION_STR " B=EXIT START=SAVE "
|
||||
#define WAITVBL swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank(); swiWaitForVBlank();
|
||||
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!
|
||||
// ---------------------------------------------------------------------------
|
||||
void SaveConfig(bool bShow)
|
||||
{
|
||||
FILE *fp;
|
||||
int slot = 0;
|
||||
|
||||
if (bShow) dsPrintValue(0,23,0, (char*)" SAVING CONFIGURATION ");
|
||||
|
||||
// Set the global configuration version number...
|
||||
allConfigs.config_ver = CONFIG_VER;
|
||||
|
||||
// Find the slot we should save into...
|
||||
for (slot=0; slot<MAX_CONFIGS; slot++)
|
||||
{
|
||||
if (strncmp(allConfigs.cart[slot].half_digest, myCartInfo.half_digest, 16) == 0) // Got a match?!
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (strcmp(allConfigs.cart[slot].half_digest, "xxxxxxxxxxxxxxxx") == 0) // Didn't find it... use a blank slot...
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
allConfigs.cart[slot] = myCartInfo;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Compute the CRC32 of everything and we can check this as integrity in the future...
|
||||
// -------------------------------------------------------------------------------------
|
||||
u8 *ptr=(u8*)&allConfigs;
|
||||
allConfigs.crc32 = 0x00000000;
|
||||
for (u32 i=0; i < sizeof(allConfigs) - 4; i++)
|
||||
{
|
||||
allConfigs.crc32 += *ptr++;
|
||||
}
|
||||
|
||||
DIR* dir = opendir("/data");
|
||||
if (dir)
|
||||
{
|
||||
closedir(dir); // Directory exists.
|
||||
}
|
||||
else
|
||||
{
|
||||
mkdir("/data", 0777); // Doesn't exist - make it...
|
||||
}
|
||||
fp = fopen("/data/A7800DS.DAT", "wb+");
|
||||
if (fp != NULL)
|
||||
{
|
||||
fwrite(&allConfigs, sizeof(allConfigs), 1, fp);
|
||||
fclose(fp);
|
||||
} else dsPrintValue(2,20,0, (char*)" ERROR SAVING CONFIG FILE ");
|
||||
|
||||
if (bShow)
|
||||
{
|
||||
WAITVBL;WAITVBL;WAITVBL;WAITVBL;WAITVBL;
|
||||
dsPrintValue(0,23, 0, (char *)CONFIG_INSTRUCTION_STR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// After settings hae changed, we call this to apply the new options to the game being played.
|
||||
// This is also called when loading a game and after the configuration if read from StelaDS.DAT
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
static void ApplyOptions(void)
|
||||
{
|
||||
extern u8 bRefreshXY, frameSkipMask;
|
||||
extern unsigned char keyboard_data[];
|
||||
|
||||
bRefreshXY = true;
|
||||
|
||||
keyboard_data[15] = myCartInfo.diff1;
|
||||
keyboard_data[16] = myCartInfo.diff2;
|
||||
|
||||
frameSkipMask = 0xFF; // Assume frameskip disabled until proven otherwise directly below
|
||||
if (myCartInfo.frameSkip == FRAMESKIP_MEDIUM) frameSkipMask = 0x03;
|
||||
if (myCartInfo.frameSkip == FRAMESKIP_AGGRESSIVE) frameSkipMask = 0x01;
|
||||
|
||||
region_Reset();
|
||||
}
|
||||
|
||||
|
||||
static void SetDefaultGameConfig(void)
|
||||
{
|
||||
// Init the entire database
|
||||
for (int slot=0; slot<MAX_CONFIGS; slot++)
|
||||
{
|
||||
strcpy(allConfigs.cart[slot].half_digest, "xxxxxxxxxxxxxxxx");
|
||||
// TBD - do more?
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Find the A7800DS.DAT file and load it... if it doesn't exist, then
|
||||
// default values will be used for the entire configuration database...
|
||||
// -------------------------------------------------------------------------
|
||||
void LoadConfig(void)
|
||||
{
|
||||
bool bInitDatabase = true;
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen("/data/A7800DS.DAT", "rb");
|
||||
if (fp != NULL)
|
||||
{
|
||||
fread(&allConfigs, sizeof(allConfigs), 1, fp);
|
||||
fclose(fp);
|
||||
|
||||
if (allConfigs.config_ver == CONFIG_VER)
|
||||
{
|
||||
bInitDatabase = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (bInitDatabase)
|
||||
{
|
||||
dsPrintValue(0,1,0, (char*)"PLEASE WAIT...");
|
||||
memset(&allConfigs, 0x00, sizeof(allConfigs));
|
||||
allConfigs.config_ver = CONFIG_VER;
|
||||
SetDefaultGameConfig();
|
||||
SaveConfig(FALSE);
|
||||
dsPrintValue(0,1,0, (char*)" ");
|
||||
}
|
||||
|
||||
ApplyOptions();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Options are handled here... we have a number of things the user can tweak
|
||||
// and these options are applied immediately. The user can also save off
|
||||
// their option choices for the currently running game into the A7800DS.DAT
|
||||
// configuration database. When games are loaded back up, A7800DS.DAT is read
|
||||
// to see if we have a match and the user settings can be restored for the game.
|
||||
// ------------------------------------------------------------------------------
|
||||
struct options_t
|
||||
{
|
||||
const char *label;
|
||||
u8 isNumeric; // 0=String List, 1=Positive 8-bit, 2=Negative 8-bit
|
||||
const char *option[15];
|
||||
u8 *option_val;
|
||||
u8 option_max;
|
||||
};
|
||||
|
||||
const struct options_t Game_Option_Table[] =
|
||||
{
|
||||
{"CART TYPE", 0, {"NORMAL/FLAT", "SUPERCART", "SUPER LARGE", "SUPER RAM", "SUPER ROM", "SUPER RAM X2", "ABSOLUTE", "ACTIVISION", "FRACTALUS", "FLAT WITH RAM", "BANKSETS", "BANKSETS RAM", "BANKSETS HALT"},&myCartInfo.cardtype, 13},
|
||||
{"HIGHSCORE", 0, {"DISABLED", "ENABLED"}, &myCartInfo.hsc, 2},
|
||||
{"FRAMESKIP", 0, {"DISABLED", "MEDIUM 3/4", "HIGH 1/2"}, &myCartInfo.frameSkip, 3},
|
||||
{"POKEY", 0, {"NONE", "AT 4000", "AT 450", "AT 800"}, &myCartInfo.pokeyType, 4},
|
||||
{"LEFT DIFF", 0, {"A", "B"}, &myCartInfo.diff1, 2},
|
||||
{"RIGHT DIFF", 0, {"A", "B"}, &myCartInfo.diff2, 2},
|
||||
{"PALETTE", 0, {"CRT V2 COOL", "CRT V2 WARM", "CRT V2 HOT"}, &myCartInfo.palette, 3},
|
||||
{"LEFT JOY", 0, {"NONE", "JOYSTICK", "LIGHTGUN", "PADDLES", "TWIN STICKS", "SOTA", "SNES2ATARI"}, &myCartInfo.cardctrl1, 7},
|
||||
{"RIGHT JOY", 0, {"NONE", "JOYSTICK", "LIGHTGUN", "PADDLES", "TWIN STICKS", "SOTA", "SNES2ATARI"}, &myCartInfo.cardctrl2, 7},
|
||||
{"X BUTTON", 0, {"DEFAULT", "PAN UP", "PAN DOWN", "JOY UP", "JOY DOWN", "JOY LEFT", "JOY RIGHT", "JOY B1", "JOY B2", "CONSOLE PAUSE"}, &myCartInfo.xButton, 10},
|
||||
{"Y BUTTON", 0, {"DEFAULT", "PAN UP", "PAN DOWN", "JOY UP", "JOY DOWN", "JOY LEFT", "JOY RIGHT", "JOY B1", "JOY B2", "CONSOLE PAUSE"}, &myCartInfo.yButton, 10},
|
||||
{"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", "+234"}, (u8*)&myCartInfo.yScale, 2},
|
||||
{"X JIGGLE", 1, {"+1", "+256"}, (u8*)&myCartInfo.xJiggle, 2},
|
||||
{"Y JIGGLE", 1, {"+1", "+256"}, (u8*)&myCartInfo.yJiggle, 2},
|
||||
|
||||
{NULL, 0, {"", ""}, NULL, 1},
|
||||
};
|
||||
|
||||
void display_line(u8 idx, u8 highlight)
|
||||
{
|
||||
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));
|
||||
}
|
||||
else if (Game_Option_Table[idx].isNumeric == 2) // Signed 16 bit
|
||||
{
|
||||
sprintf(strBuf, " %-11s : %-15d", Game_Option_Table[idx].label, *((s16*)Game_Option_Table[idx].option_val));
|
||||
}
|
||||
else // Array of strings
|
||||
{
|
||||
sprintf(strBuf, " %-11s : %-15s", Game_Option_Table[idx].label, Game_Option_Table[idx].option[*(Game_Option_Table[idx].option_val)]);
|
||||
}
|
||||
dsPrintValue(1,5+idx, highlight, strBuf);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Display the current list of options...
|
||||
// ------------------------------------------------------------------
|
||||
static int display_options_list(bool bFullDisplay)
|
||||
{
|
||||
int len=0;
|
||||
|
||||
if (bFullDisplay)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
display_line(len, (len==0 ? 1:0));
|
||||
len++;
|
||||
if (Game_Option_Table[len].label == NULL) break;
|
||||
}
|
||||
|
||||
// Blank out rest of the screen... option menus are of different lengths...
|
||||
for (int i=len; i<20; i++)
|
||||
{
|
||||
dsPrintValue(1,6+i, 0, (char *)" ");
|
||||
}
|
||||
}
|
||||
|
||||
dsPrintValue(0,23, 0, (char *)CONFIG_INSTRUCTION_STR);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Allows the user to move the cursor up and down through the various table
|
||||
// enties above to select options for the game they wish to play.
|
||||
// -----------------------------------------------------------------------------
|
||||
void ShowConfig(void)
|
||||
{
|
||||
int optionHighlighted;
|
||||
int idx;
|
||||
bool bDone=false;
|
||||
int keys_pressed;
|
||||
int last_keys_pressed = 999;
|
||||
|
||||
// Show the Options background...
|
||||
decompress(bgFileSelTiles, bgGetGfxPtr(bg0b), LZ77Vram);
|
||||
decompress(bgFileSelMap, (void*) bgGetMapPtr(bg0b), LZ77Vram);
|
||||
dmaCopy((void *) bgFileSelPal,(u16*) BG_PALETTE_SUB,256*2);
|
||||
unsigned short dmaVal = *(bgGetMapPtr(bg1b) +31*32);
|
||||
dmaFillWords(dmaVal | (dmaVal<<16),(void*) bgGetMapPtr(bg1b),32*24*2);
|
||||
swiWaitForVBlank();
|
||||
|
||||
|
||||
idx=display_options_list(true);
|
||||
optionHighlighted = 0;
|
||||
while (!bDone)
|
||||
{
|
||||
keys_pressed = keysCurrent();
|
||||
if (keys_pressed != last_keys_pressed)
|
||||
{
|
||||
last_keys_pressed = keys_pressed;
|
||||
if (keysCurrent() & KEY_UP) // Previous option
|
||||
{
|
||||
display_line(optionHighlighted, 0);
|
||||
if (optionHighlighted > 0) optionHighlighted--; else optionHighlighted=(idx-1);
|
||||
display_line(optionHighlighted, 1);
|
||||
}
|
||||
if (keysCurrent() & KEY_DOWN) // Next option
|
||||
{
|
||||
display_line(optionHighlighted, 0);
|
||||
if (optionHighlighted < (idx-1)) optionHighlighted++; else optionHighlighted=0;
|
||||
display_line(optionHighlighted, 1);
|
||||
}
|
||||
|
||||
if (keysCurrent() & KEY_RIGHT) // Toggle option clockwise
|
||||
{
|
||||
if (Game_Option_Table[optionHighlighted].isNumeric == 1)
|
||||
{
|
||||
if (*(Game_Option_Table[optionHighlighted].option_val) < atoi(Game_Option_Table[optionHighlighted].option[1]))
|
||||
{
|
||||
*(Game_Option_Table[optionHighlighted].option_val) += 1;
|
||||
}
|
||||
}
|
||||
else if (Game_Option_Table[optionHighlighted].isNumeric == 2)
|
||||
{
|
||||
if (*((s16*)Game_Option_Table[optionHighlighted].option_val) < atoi(Game_Option_Table[optionHighlighted].option[1]))
|
||||
{
|
||||
*((s16*)Game_Option_Table[optionHighlighted].option_val) += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*(Game_Option_Table[optionHighlighted].option_val) = (*(Game_Option_Table[optionHighlighted].option_val) + 1) % Game_Option_Table[optionHighlighted].option_max;
|
||||
}
|
||||
display_line(optionHighlighted, 1);
|
||||
ApplyOptions();
|
||||
}
|
||||
if (keysCurrent() & KEY_LEFT) // Toggle option counterclockwise
|
||||
{
|
||||
if (Game_Option_Table[optionHighlighted].isNumeric == 1)
|
||||
{
|
||||
if (*(Game_Option_Table[optionHighlighted].option_val) > atoi(Game_Option_Table[optionHighlighted].option[0]))
|
||||
{
|
||||
*(Game_Option_Table[optionHighlighted].option_val) -= 1;
|
||||
}
|
||||
}
|
||||
else if (Game_Option_Table[optionHighlighted].isNumeric == 2)
|
||||
{
|
||||
if (*((s16*)Game_Option_Table[optionHighlighted].option_val) > atoi(Game_Option_Table[optionHighlighted].option[0]))
|
||||
{
|
||||
*((s16*)Game_Option_Table[optionHighlighted].option_val) -= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*(Game_Option_Table[optionHighlighted].option_val)) == 0)
|
||||
*(Game_Option_Table[optionHighlighted].option_val) = Game_Option_Table[optionHighlighted].option_max -1;
|
||||
else
|
||||
*(Game_Option_Table[optionHighlighted].option_val) = (*(Game_Option_Table[optionHighlighted].option_val) - 1) % Game_Option_Table[optionHighlighted].option_max;
|
||||
}
|
||||
display_line(optionHighlighted, 1);
|
||||
ApplyOptions();
|
||||
}
|
||||
if (keysCurrent() & KEY_START) // Save Options
|
||||
{
|
||||
SaveConfig(TRUE);
|
||||
}
|
||||
if (keysCurrent() & KEY_SELECT) // Restore Defaults
|
||||
{
|
||||
//extern void CartSetDefaultFromInternalDatabase(void);
|
||||
//CartSetDefaultFromInternalDatabase();
|
||||
display_options_list(true);
|
||||
optionHighlighted = 0;
|
||||
}
|
||||
if ((keysCurrent() & KEY_B) || (keysCurrent() & KEY_A)) // Exit options
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
// Restore original bottom graphic
|
||||
dsShowScreenMain(false);
|
||||
|
||||
// Give a third of a second time delay...
|
||||
for (int i=0; i<20; i++)
|
||||
{
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// End of Line
|
||||
|
69
arm9/source/config.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
// =====================================================================================
|
||||
// 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 __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#include <nds.h>
|
||||
#include "Database.h"
|
||||
#include "Cartridge.h"
|
||||
|
||||
// ---------------------------
|
||||
// Config handling...
|
||||
// ---------------------------
|
||||
#define CONFIG_VER 0x000B
|
||||
|
||||
#define MAX_CONFIGS 640
|
||||
|
||||
struct AllConfig_t
|
||||
{
|
||||
u16 config_ver;
|
||||
u8 global_buttonAB;
|
||||
u8 global_showBios;
|
||||
u8 global_spare1;
|
||||
u8 global_spare2;
|
||||
u8 global_spare3;
|
||||
u8 global_spare4;
|
||||
u8 global_spare5;
|
||||
u8 global_spare6;
|
||||
u8 global_spare7;
|
||||
u8 global_spare10;
|
||||
u8 global_spare11;
|
||||
u8 global_spare12;
|
||||
u8 global_spare13;
|
||||
u8 global_spare14;
|
||||
u8 global_unused[512];
|
||||
Database_Entry cart[MAX_CONFIGS];
|
||||
u32 crc32;
|
||||
};
|
||||
|
||||
extern struct AllConfig_t allConfigs;
|
||||
|
||||
void LoadConfig(void);
|
||||
void ShowConfig(void);
|
||||
void SaveConfig(bool bShow);
|
||||
|
||||
#endif
|
|
@ -1,53 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Archive.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Archive.h"
|
||||
#define ARCHIVE_SOURCE "Archive.cpp"
|
||||
|
||||
#define _MAX_PATH 128
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetUncompressedFileSize
|
||||
// ----------------------------------------------------------------------------
|
||||
uint archive_GetUncompressedFileSize(char* filename)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Uncompress
|
||||
// ----------------------------------------------------------------------------
|
||||
bool archive_Uncompress(char* filename, byte* data, uint size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Compress
|
||||
// ----------------------------------------------------------------------------
|
||||
bool archive_Compress(char* zipFilename, char* filename, const byte* data, uint size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Archive.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef ARCHIVE_H
|
||||
#define ARCHIVE_H
|
||||
|
||||
#include <string.h>
|
||||
#include "Logger.h"
|
||||
#include "Cartridge.h"
|
||||
//#include "zip.h"
|
||||
//#include "unzip.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
extern uint archive_GetUncompressedFileSize(char* filename);
|
||||
extern bool archive_Uncompress(char* filename, byte* data, uint size);
|
||||
extern bool archive_Compress(char* zipFilename, char* filename, const byte* data, uint size);
|
||||
|
||||
#endif
|
|
@ -1,91 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Bios.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Bios.h"
|
||||
#define BIOS_SOURCE "Bios.cpp"
|
||||
|
||||
bool bios_enabled = false;
|
||||
char bios_filename[128];
|
||||
|
||||
static byte* bios_data = NULL;
|
||||
static word bios_size = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool bios_Load(char* filename) {
|
||||
if(strlen(filename) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bios_Release( );
|
||||
|
||||
bios_size = archive_GetUncompressedFileSize(filename);
|
||||
if(bios_size == 0) {
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
return false;
|
||||
}
|
||||
fseek(file, 0, SEEK_END);
|
||||
bios_size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
bios_data = (byte *) malloc(bios_size);
|
||||
fread(bios_data, 1, bios_size, file);
|
||||
fclose(file);
|
||||
}
|
||||
else {
|
||||
bios_data = (byte *) malloc(bios_size);
|
||||
archive_Uncompress(filename, bios_data, bios_size);
|
||||
}
|
||||
|
||||
strcpy(bios_filename,filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsLoaded
|
||||
// ----------------------------------------------------------------------------
|
||||
bool bios_IsLoaded( ) {
|
||||
return (bios_data != NULL)? true: false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Release
|
||||
// ----------------------------------------------------------------------------
|
||||
void bios_Release( ) {
|
||||
if(bios_data) {
|
||||
free(bios_data);
|
||||
bios_size = 0;
|
||||
bios_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Store
|
||||
// ----------------------------------------------------------------------------
|
||||
void bios_Store( ) {
|
||||
if(bios_data != NULL && bios_enabled) {
|
||||
memory_WriteROM(65536 - bios_size, bios_size, bios_data);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Bios.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BIOS_H
|
||||
#define BIOS_H
|
||||
|
||||
#include <string.h>
|
||||
#include "Memory.h"
|
||||
#include "Archive.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
extern bool bios_Load(char* filename);
|
||||
extern bool bios_IsLoaded( );
|
||||
extern void bios_Store( );
|
||||
extern void bios_Release( );
|
||||
extern char bios_filename[128];
|
||||
extern bool bios_enabled;
|
||||
|
||||
#endif
|
|
@ -30,89 +30,92 @@
|
|||
#include "Equates.h"
|
||||
#include "Memory.h"
|
||||
#include "Hash.h"
|
||||
#include "Logger.h"
|
||||
#include "Pokey.h"
|
||||
#include "Archive.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
#define MAX_CART_SIZE (1024 * 1024) // 1MB Cart is HUGE!
|
||||
|
||||
extern u8 use_composite_filtering;
|
||||
extern u8 bios_show_counter;
|
||||
extern u8 bios_available;
|
||||
|
||||
#define CARTRIDGE_CONTROLLER_NONE 0
|
||||
#define CARTRIDGE_CONTROLLER_JOYSTICK 1
|
||||
#define CARTRIDGE_CONTROLLER_LIGHTGUN 2
|
||||
#define CARTRIDGE_CONTROLLER_PADDLES 3
|
||||
#define CARTRIDGE_CONTROLLER_TWIN_STICKS 4
|
||||
#define CARTRIDGE_CONTROLLER_SOTA 5
|
||||
#define CARTRIDGE_CONTROLLER_SNES2ATARI 6
|
||||
|
||||
#define JOY CARTRIDGE_CONTROLLER_JOYSTICK
|
||||
#define LGN CARTRIDGE_CONTROLLER_LIGHTGUN
|
||||
#define PAD CARTRIDGE_CONTROLLER_PADDLES
|
||||
#define TWIN CARTRIDGE_CONTROLLER_TWIN_STICKS
|
||||
#define SOTA CARTRIDGE_CONTROLLER_SOTA
|
||||
#define SNES CARTRIDGE_CONTROLLER_SNES2ATARI
|
||||
|
||||
#define CARTRIDGE_CYCLE_STEALING_MASK 0x01
|
||||
#define CARTRIDGE_WSYNC_MASK 0x02
|
||||
|
||||
#define POKEY_NONE 0
|
||||
#define POKEY_AT_4000 1
|
||||
#define POKEY_AT_450 2
|
||||
#define POKEY_AT_800 3
|
||||
|
||||
#define FRAMESKIP_DISABLE 0
|
||||
#define FRAMESKIP_MEDIUM 1
|
||||
#define FRAMESKIP_AGGRESSIVE 2
|
||||
|
||||
#define HSC_YES true
|
||||
#define HSC_NO false
|
||||
|
||||
#define NTSC 0
|
||||
#define PAL 1
|
||||
|
||||
#define STEAL_CYCLE true
|
||||
#define NO_STEALING false
|
||||
|
||||
#define USES_WSYNC true
|
||||
#define SKIP_WSYNC false
|
||||
|
||||
#define CARTRIDGE_TYPE_NORMAL 0
|
||||
#define CARTRIDGE_TYPE_SUPERCART 1
|
||||
#define CARTRIDGE_TYPE_SUPERCART_LARGE 2
|
||||
#define CARTRIDGE_TYPE_SUPERCART_RAM 3
|
||||
#define CARTRIDGE_TYPE_SUPERCART_ROM 4
|
||||
#define CARTRIDGE_TYPE_ABSOLUTE 5
|
||||
#define CARTRIDGE_TYPE_ACTIVISION 6
|
||||
|
||||
#define CARTRIDGE_CONTROLLER_NONE 0
|
||||
#define CARTRIDGE_CONTROLLER_JOYSTICK 1
|
||||
#define CARTRIDGE_CONTROLLER_LIGHTGUN 2
|
||||
#define CARTRIDGE_CONTROLLER_PADDLES 3
|
||||
#define CARTRIDGE_CONTROLLER_TWIN_STICKS 4
|
||||
#define CARTRIDGE_CONTROLLER_SOTA 5
|
||||
|
||||
#define CARTRIDGE_CYCLE_STEALING_MASK 0x01
|
||||
#define CARTRIDGE_WSYNC_MASK 0x02
|
||||
|
||||
#define POKEY_NONE 0
|
||||
#define POKEY_AT_4000 1
|
||||
#define POKEY_AT_450 2
|
||||
|
||||
#define HSC_YES true
|
||||
#define HSC_NO false
|
||||
|
||||
#define NTSC 0
|
||||
#define PAL 1
|
||||
|
||||
#define JOY CARTRIDGE_CONTROLLER_JOYSTICK
|
||||
#define LGN CARTRIDGE_CONTROLLER_LIGHTGUN
|
||||
#define PAD CARTRIDGE_CONTROLLER_PADDLES
|
||||
#define TWIN CARTRIDGE_CONTROLLER_TWIN_STICKS
|
||||
#define SOTA CARTRIDGE_CONTROLLER_SOTA
|
||||
#define CARTRIDGE_TYPE_SUPERCART_RAMX2 5
|
||||
#define CARTRIDGE_TYPE_ABSOLUTE 6
|
||||
#define CARTRIDGE_TYPE_ACTIVISION 7
|
||||
#define CARTRIDGE_TYPE_FRACTALUS 8
|
||||
#define CARTRIDGE_TYPE_FLAT_WITH_RAM 9
|
||||
#define CARTRIDGE_TYPE_BANKSETS 10
|
||||
#define CARTRIDGE_TYPE_BANKSETS_RAM 11
|
||||
#define CARTRIDGE_TYPE_BANKSETS_HALTRAM 12
|
||||
|
||||
#define CT_NORMAL CARTRIDGE_TYPE_NORMAL
|
||||
#define CT_SUPCAR CARTRIDGE_TYPE_SUPERCART
|
||||
#define CT_SUPLRG CARTRIDGE_TYPE_SUPERCART_LARGE
|
||||
#define CT_SUPRAM CARTRIDGE_TYPE_SUPERCART_RAM
|
||||
#define CT_SUPRAMX2 CARTRIDGE_TYPE_SUPERCART_RAMX2
|
||||
#define CT_SUPROM CARTRIDGE_TYPE_SUPERCART_ROM
|
||||
#define CT_ABSOLU CARTRIDGE_TYPE_ABSOLUTE
|
||||
#define CT_ACTVIS CARTRIDGE_TYPE_ACTIVISION
|
||||
|
||||
|
||||
#define STEAL_CYCLE true
|
||||
#define NO_STEALING false
|
||||
#define USES_WSYNC true
|
||||
#define SKIP_WSYNC false
|
||||
|
||||
#define CT_FRACTALUS CARTRIDGE_TYPE_FRACTALUS
|
||||
#define CT_FLATWRAM CARTRIDGE_TYPE_FLAT_WITH_RAM
|
||||
#define CT_BANKSETS CARTRIDGE_TYPE_BANKSETS
|
||||
#define CT_BANKSRAM CARTRIDGE_TYPE_BANKSETS_RAM
|
||||
#define CT_BANKSHALT CARTRIDGE_TYPE_BANKSETS_HALTRAM
|
||||
|
||||
extern bool cartridge_Load(char* filename);
|
||||
extern bool cartridge_Load_buffer(char* rom_buffer, int rom_size);
|
||||
extern void cartridge_Store( );
|
||||
extern void cartridge_StoreBank(byte bank);
|
||||
extern void cartridge_Write(word address, byte data);
|
||||
extern bool cartridge_IsLoaded( );
|
||||
extern void cartridge_Release( );
|
||||
extern char cartridge_title[128];
|
||||
extern char cartridge_description[128];
|
||||
extern char cartridge_year[128];
|
||||
extern char cartridge_maker[128];
|
||||
extern byte cartridge_digest[128];
|
||||
extern char cartridge_filename[128];
|
||||
extern byte cartridge_type;
|
||||
extern byte cartridge_region;
|
||||
extern byte cartridge_pokey;
|
||||
extern bool cartridge_hsc_enabled;
|
||||
extern byte cartridge_controller[2];
|
||||
extern byte cartridge_bank;
|
||||
extern int cartridge_xOffset;
|
||||
extern int cartridge_yOffset;
|
||||
extern int cartridge_xScale;
|
||||
extern int cartridge_yScale;
|
||||
extern bool cartridge_steals_cycles;
|
||||
extern bool cartridge_uses_wsync;
|
||||
extern uint cartridge_diff1;
|
||||
extern uint cartridge_diff2;
|
||||
|
||||
|
||||
extern void bios_check_and_load(void);
|
||||
extern void bios_Store(void);
|
||||
extern char cartridge_title[256];
|
||||
extern byte cartridge_digest[256];
|
||||
extern char cartridge_filename[256];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,232 +22,471 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Database.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Database.h"
|
||||
#include "ProSystem.h"
|
||||
#include "../config.h"
|
||||
|
||||
#define DATABASE_SOURCE "Database.cpp"
|
||||
|
||||
bool database_enabled = true;
|
||||
typedef struct {
|
||||
char digest[33];
|
||||
char header_name[33];
|
||||
uint cardtype;
|
||||
byte pokeyType;
|
||||
uint cardctrl1;
|
||||
uint cardctrl2;
|
||||
uint diff1;
|
||||
uint diff2;
|
||||
uint cardregion;
|
||||
bool steals_cycles;
|
||||
bool uses_wsync;
|
||||
bool hsc;
|
||||
int xOffset;
|
||||
int yOffset;
|
||||
int xScale;
|
||||
int yScale;
|
||||
} Database_Entry;
|
||||
Database_Entry myCartInfo __attribute__((section(".dtcm")));
|
||||
extern uint cartridge_size;
|
||||
|
||||
// To get the md5sum of an .a78 file with header in Linux: dd bs=1 skip=128 if=somefile.a78 | md5sum
|
||||
|
||||
Database_Entry game_list[] = {
|
||||
{"f5150c0fc1948832211e57852abb0c6e", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=7800 Utility Cart
|
||||
{"4332c24e4f3bc72e7fe1b77adf66c2b7", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=3D Asteroids
|
||||
{"0be996d25144966d5541c9eb4919b289", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Ace Of Aces
|
||||
{"877dcc97a775ed55081864b2dbf5f1e2", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, NO_STEALING, USES_WSYNC, HSC_NO, 7, 30, 264, 230}, // title=Alien Brigade
|
||||
{"212ee2a6e66d8bb7fbf26f343cc8dc19", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 17, 256, 200}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
|
||||
{"07342c78619ba6ffcc61c10e907e3b50", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 256, 230}, // title=Asteroids
|
||||
{"a65f79ad4a0bbdecd59d5f7eb3623fd7", "Asteroids Deluxe (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 256, 230}, // title=Asteroids Deluxe
|
||||
{"3d38281ed8a8d8c7cd457a18c92c8604", "Astro Blaster", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 17, 320, 210}, // title=Astro Blaster
|
||||
{"a51e5df28a0fe8c52e9d28fb5f8e44a6", "Astro Fighter", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 16, 320, 210}, // title=Astro Fighter
|
||||
{"7cdfbe37634e7dcd4dc67db7edbcd3ba", "Baby Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 30, 22, 320, 220}, // title=Baby Pac Man
|
||||
{"8fc3a695eaea3984912d98ed4a543376", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Ballblazer
|
||||
{"42682415906c21c6af80e4198403ffda", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Barnyard Blaster
|
||||
{"f5f6b69c5eb4b55fc163158d1a6b423e", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Basketbrawl
|
||||
{"78b1061d651ef806becac1dd3fda29a0", "Beef Drop", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, SKIP_WSYNC, HSC_YES, 0, 16, 256, 220}, // title=Beef Drop (Final Atariage)
|
||||
{"4e325918a8b3bbcf2f9405040abcfc6d", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 26, 256, 220}, // title=BonQ (found on Atairage Age site)
|
||||
{"9fa7743a016c9b7015ee1d386326f88e", "b*nQ", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, SKIP_WSYNC, HSC_YES, 0, 26, 256, 220}, // title=BonQ (final Atariage)
|
||||
{"5a09946e57dbe30408a8f253a28d07db", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 24, 24, 300, 230}, // title=Centipede
|
||||
{"20660b667df538ec32a8e1b998438604", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 24, 24, 300, 230}, // title=Centipede - Frameless Hack
|
||||
{"93e4387864b014c155d7c17877990d1e", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Choplifter
|
||||
{"2e8e28f6ad8b9b9267d518d880c73ebb", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 20, 256, 220}, // title=Commando
|
||||
{"db691469128d9a4217ec7e315930b646", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Crack'ed
|
||||
{"a94e4560b6ad053a1c24e096f1262ebf", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Crossbow
|
||||
{"179b76ff729d4849b8f66a502398acae", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 21, 256, 220}, // title=Dark Chambers
|
||||
{"95ac811c7d27af0032ba090f28c107bd", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Desert Falcon
|
||||
{"731879ea82fc0ca245e39e036fe293e6", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Dig Dug
|
||||
{"5e332fbfc1e0fc74223d2e73271ce650", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Donkey Kong Jr
|
||||
{"19f1ee292a23636bd57d408b62de79c7", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Donkey Kong
|
||||
{"c3107d3e3e17d67e3a11d47a5946a4f3", "DONKEY KONG XM", CT_SUPLRG, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 20, 256, 210}, // title=Donkey Kong XM Demo (purposely set HSC to false - game HSC is buggy)
|
||||
{"543484c00ba233736bcaba2da20eeea9", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, NO_STEALING, SKIP_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Double Dragon
|
||||
{"94009ccfdcd4f55d24033ca06269ba6a", "Dragon's Descent", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 24, 256, 234}, // title=Dragon's Descent 1.7
|
||||
{"fab1290f9a4c4f2b4d831c8a57f969f5", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 256, 230}, // title=Draker Quest
|
||||
{"a9f29004412621f20ad9f5c51cc11486", "Draker Quest II", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 24, 256, 230}, // title=Draker Quest II
|
||||
{"b3143adbbb7d7d189e918e5b29d55a72", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 23, 256, 220}, // title=Dungeon Stalker (homebrew)
|
||||
{"faea27017447dd8bae677d91125a8135", "EXO", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 256, 230}, // title=E.X.O.
|
||||
{"2251a6a0f3aec84cc0aff66fc9fa91e8", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_ABSOLU, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=F-18 Hornet
|
||||
{"6287727ab36391a62f728bbdee88675c", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Failsafe (homebrew)
|
||||
{"d25d5d19188e9f149977c49eb0367cd1", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Fatal Run
|
||||
{"07dbbfe612a0a28e283c01545e59f25e", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Fight Night
|
||||
{"cf76b00244105b8e03cdc37677ec1073", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Food Fight
|
||||
{"e7d89669a7f92ec2cc99d9663a28671c", "Frenzy (w-Berzerk)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, NO_STEALING, USES_WSYNC, HSC_YES, 30, 15, 320, 205}, // title=Frenzy (with Berzerk) (homebrew)
|
||||
{"6053233cb59c0b4ca633623fd76c4576", "Froggie", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 34, 16, 320, 205}, // title=Froggie (homebrew)
|
||||
{"fb8d803b328b2e442548f7799cfa9a4a", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Galaga
|
||||
{"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "Galaxian", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 13, 256, 200}, // title=Galaxian
|
||||
{"06204dadc975be5e5e37e7cc66f984cf", "Galaga", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Gato
|
||||
{"e443f7fb5be3283dd44c0f5d80c3a7b3", "GoSub", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 12, 22, 280, 230}, // title=GoSub
|
||||
{"fd9e78e201b6baafddfd3e1fbfe6ba31", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Hat Trick
|
||||
{"c3672482ca93f70eafd9134b936c3feb", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 25, 256, 230}, // title=Ikari Warriors
|
||||
{"baebc9246c087e893dfa489632157180", "Impossible Mission", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Impossible Mission
|
||||
{"1745feadabb24e7cefc375904c73fa4c", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Impossible Mission
|
||||
{"045fd12050b7f2b842d5970f2414e912", "Jinks", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 234}, // title=Jinks
|
||||
{"f18b3b897a25ab3885b43b4bd141b396", "Joust", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 256, 234}, // title=Joust
|
||||
{"e54edc299e72d22d0ba05d16f3393e8c", "Jr. Pac-Man (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Jr Pac-Man
|
||||
{"c3a5a8692a423d43d9d28dd5b7d109d9", "Karateka", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Karateka
|
||||
{"17b3b764d33eae9b5260f01df7bb9d2f", "Klax", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 28, 256, 234}, // title=Klax
|
||||
{"f57d0af323d4e173fb49ed447f0563d7", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, NO_STEALING, SKIP_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Kung Fu Master
|
||||
{"431ca060201ee1f9eb49d44962874049", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Mario Bros.
|
||||
{"37b5692e33a98115e574185fa8398c22", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Mat Mania Challenge
|
||||
{"f2f5e5841e4dda89a2faf8933dc33ea6", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Mean 18 Ultimate Golf
|
||||
{"bedc30ec43587e0c98fc38c39c1ef9d0", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Meltdown
|
||||
{"c3f6201d6a9388e860328c963a3301cc", "Meteor Shower", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 21, 256, 220}, // title=Meteor Shower
|
||||
{"bc1e905db1008493a9632aa83ab4682b", "Midnight Mutants", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 21, 256, 226}, // title=Midnight Mutants
|
||||
{"017066f522908081ec3ee624f5e4a8aa", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, NO_STEALING, SKIP_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Missing in Action
|
||||
{"181a9978d9da7a7e21f770808cc681f2", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 320, 230}, // title=Merlain
|
||||
{"9ff38ea62004201d870caa8bd9463525", "Moon Cresta (NTSC)", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 13, 320, 210}, // title=Moon Cresta
|
||||
{"3bc8f554cf86f8132a623cc2201a564b", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Motor Psycho
|
||||
{"fc0ea52a9fac557251b65ee680d951e5", "Ms. Pac-Man", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Ms. Pac-Man
|
||||
{"220121f771fc4b98cef97dc040e8d378", "Ninja Golf", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 10, 22, 270, 220}, // title=Ninja Golf
|
||||
{"74569571a208f8b0b1ccfb22d7c914e1", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 12, 256, 220}, // title=One On One
|
||||
{"5013b69cb05b21a1194ce48517df7bfc", "Pac-Man Collection", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 19, 256, 216}, // title=Pac-Man Collection (homebrew)
|
||||
{"044657294450c869c45e7ef61f4870de", "Pac-Man Collection - 40th Anniv", CT_SUPCAR, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 256, 220}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Pokey Version
|
||||
{"e66f3812d74724cdb3ae489e5c7d1c0e", "Pac-Man XM", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 25, 256, 220}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Forced TIA
|
||||
{"1a5207870dec6fae9111cb747e20d8e3", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Pete Rose Baseball
|
||||
{"ec206c8db4316eb1ebce9fc960da7d8f", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Pit Fighter
|
||||
{"33aea1e2b6634a1dec8c7006d9afda22", "Planet Smashers", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 18, 256, 226}, // title=Planet Smashers
|
||||
{"86546808dc60961cdb1b20e761c50ab1", "Plutos", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Plutos (non-XM)
|
||||
{"74f0283c566bdee8543e4fdc5cb8b201", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Plutos XM
|
||||
{"584582bb09ee8122e7fc09dc7d1ed813", "Pole Position II", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 35, 22, 320, 230}, // title=Pole Position II
|
||||
{"1745feadabb24e7cefc375904c73fa4c", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Possible Mission
|
||||
{"0710aa2620435230da6a7cf3f620210d", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 18, 256, 210}, // title=Popeye Demo 2.7f (homebrew)
|
||||
{"81187dbc08934214bd55187d4b8149dd", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 18, 256, 210}, // title=Popeye Demo 2.8 (homebrew)
|
||||
{"640c7827fe63082efbaffc13f7983744", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 18, 256, 210}, // title=Popeye Demo 2.9 (homebrew)
|
||||
{"631262731c193928d01365d2bc31b64f", "Popeye", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 18, 256, 210}, // title=Popeye Demo 1.0RC
|
||||
{"ac03806cef2558fc795a7d5d8dba7bc0", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Rampage
|
||||
{"bfad016d6e77eaccec74c0340aded8b9", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Realsports Baseball
|
||||
{"8f7eb10ad0bd75474abf0c6c36c08486", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Rescue On Fractalus
|
||||
{"66ecaafe1b82ae68ffc96267aaf7a4d7", "Robotron", CT_NORMAL, POKEY_NONE, TWIN,TWIN, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 5, 22, 270, 234}, // title=Robotron
|
||||
{"b6561537290e6e25e1249394366c3c63", "Robbo", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Robbo
|
||||
{"a3a85e507d6f718972b1464ce1aaf8a4", "Scramble", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 13, 320, 205}, // title=Scramble (homebrew)
|
||||
{"980c35ae9625773a450aa7ef51751c04", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Scrapyard Dog
|
||||
{"b697d9c2d1b9f6cb21041286d1bbfa7f", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Sentinel
|
||||
{"9bd70c06d3386f76f8162881699a777a", "Serpentine", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Serpentine (homebrew)
|
||||
{"771cb4609347657f63e6f0eb26036e35", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Space Duel (homebrew)
|
||||
{"6adf79558a3d7f5beca1bb8d34337417", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 30, 16, 320, 205}, // title=Space Invaders (Homebrew)
|
||||
{"19844117863cd38d4e1e4cbc867ae599", "Spire of the Ancients", CT_SUPLRG, POKEY_NONE, SOTA,SOTA, DIFF_A, DIFF_A, NTSC, NO_STEALING, USES_WSYNC, HSC_YES, 31, 25, 320, 230}, // title=Spire of the Ancients
|
||||
{"19844117863cd38d4e1e4cbc867ae599", "SotA", CT_SUPLRG, POKEY_NONE, SOTA,SOTA, DIFF_A, DIFF_A, NTSC, NO_STEALING, USES_WSYNC, HSC_YES, 31, 25, 320, 230}, // title=Spire of the Ancients
|
||||
{"cbb0746192540a13b4c7775c7ce2021f", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Summer Games
|
||||
{"81cee326b99d6831de10a566e338bd25", "Super Circus AA-NTSC-joy-4000", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 21, 256, 220}, // title=Super Circus Atariage (Pokey 4000)
|
||||
{"cc18e3b37a507c4217eb6cb1de8c8538", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Super Huey UH-IX
|
||||
{"59b5793bece1c80f77b55d60fb39cb94", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Super Skatebordin'
|
||||
{"44f862bca77d68b56b32534eda5c198d", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Tank Command
|
||||
{"1af475ff6429a160752b592f0f92b287", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Title Match Pro Wrestling
|
||||
{"a60e4b608505d1fb201703b266f754a7", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 24, 256, 230}, // title=Time Salvo
|
||||
{"c3903ab01a51222a52197dbfe6538ecf", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Tomcat F-14 Simulator
|
||||
{"208ef955fa90a29815eb097bce89bace", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Touchdown Football
|
||||
{"8d64763db3100aadc552db5e6868506a", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 16, 256, 230}, // title=Tower Toppler
|
||||
{"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", "UniWarS", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 13, 256, 200}, // title=UniWarS
|
||||
{"acf63758ecf3f3dd03e9d654ae6b69b7", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Water Ski
|
||||
{"3799d72f78dda2ee87b0ef8bf7b91186", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 0, 22, 256, 220}, // title=Winter Games
|
||||
{"05fb699db9eef564e2fe45c568746dbc", "Xenophobe", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_NO, 15, 22, 280, 234}, // title=Xenophobe
|
||||
{"d7dc17379aa25e5ae3c14b9e780c6f6d", "Xevious", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, STEAL_CYCLE, USES_WSYNC, HSC_YES, 0, 22, 256, 220}, // title=Xevious
|
||||
{"","",CT_NORMAL,0,0,0,0,0,0,0,0,0,0},
|
||||
|
||||
// The original NTSC Commercial Games
|
||||
{"0be996d25144966d", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Ace Of Aces
|
||||
{"877dcc97a775ed55", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 7, 22, 264, 230, 0}, // title=Alien Brigade
|
||||
{"07342c78619ba6ff", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 17, 256, 230, 0}, // title=Asteroids
|
||||
{"8fc3a695eaea3984", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 240, 6, 12, 262, 220, 0}, // title=Ballblazer
|
||||
{"42682415906c21c6", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 155, 0, 12, 256, 220, 0}, // title=Barnyard Blaster
|
||||
{"f5f6b69c5eb4b55f", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 2, 15, 262, 226, 0}, // title=Basketbrawl
|
||||
{"5a09946e57dbe304", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 24, 16, 300, 230, 0}, // title=Centipede
|
||||
{"93e4387864b014c1", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 210, 0, 15, 256, 226, 0}, // title=Choplifter
|
||||
{"2e8e28f6ad8b9b92", CT_SUPCAR, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 218, 0}, // title=Commando
|
||||
{"db691469128d9a42", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 165, 0, 18, 256, 229, 0}, // title=Crack'ed
|
||||
{"a94e4560b6ad053a", CT_SUPLRG, POKEY_NONE, LGN, LGN, DIFF_A, DIFF_A, NTSC, HSC_NO, 150, 9, 17, 272, 234, 0}, // title=Crossbow
|
||||
{"179b76ff729d4849", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 0, 13, 256, 219, 0}, // title=Dark Chambers
|
||||
{"95ac811c7d27af00", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 240, 6, 19, 261, 234, 0}, // title=Desert Falcon
|
||||
{"731879ea82fc0ca2", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 12, 256, 220, 0}, // title=Dig Dug
|
||||
{"5e332fbfc1e0fc74", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 14, 256, 220, 0}, // title=Donkey Kong Jr
|
||||
{"743c47f500d095f2", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 14, 256, 220, 0}, // title=Donkey Kong Jr (alt)
|
||||
{"19f1ee292a23636b", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 14, 256, 220, 0}, // title=Donkey Kong
|
||||
{"543484c00ba23373", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 0, 12, 256, 220, 0}, // title=Double Dragon
|
||||
{"2251a6a0f3aec84c", CT_ABSOLU, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 12, 256, 220, 0}, // title=F-18 Hornet
|
||||
{"d25d5d19188e9f14", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 155, 0, 12, 256, 220, 0}, // title=Fatal Run
|
||||
{"07dbbfe612a0a28e", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 12, 14, 282, 226, 0}, // title=Fight Night
|
||||
{"cf76b00244105b8e", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 17, 255, 227, 0}, // title=Food Fight
|
||||
{"fb8d803b328b2e44", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 12, 256, 229, 0}, // title=Galaga
|
||||
{"fd9e78e201b6baaf", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 250, 0, 17, 256, 227, 0}, // title=Hat Trick
|
||||
{"c3672482ca93f70e", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 180, 0, 17, 256, 230, 0}, // title=Ikari Warriors
|
||||
{"baebc9246c087e89", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 165, 0, 12, 256, 220, 0}, // title=Impossible Mission
|
||||
{"045fd12050b7f2b8", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 165, 3, 12, 261, 234, 1}, // title=Jinks
|
||||
{"f18b3b897a25ab38", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 17, 256, 234, 0}, // title=Joust
|
||||
{"c3a5a8692a423d43", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 250, 0, 12, 256, 220, 0}, // title=Karateka
|
||||
{"f57d0af323d4e173", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 22, 17, 276, 225, 0}, // title=Kung Fu Master
|
||||
{"f2f5e5841e4dda89", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Mean 18 Ultimate Golf
|
||||
{"bc1e905db1008493", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 120, 0, 13, 256, 226, 0}, // title=Midnight Mutants
|
||||
{"431ca060201ee1f9", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 14, 256, 220, 0}, // title=Mario Bros.
|
||||
{"37b5692e33a98115", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 0, 12, 256, 220, 0}, // title=Mat Mania Challenge
|
||||
{"bedc30ec43587e0c", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 165, 0, 12, 256, 220, 0}, // title=Meltdown
|
||||
{"3bc8f554cf86f813", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Motor Psycho
|
||||
{"fc0ea52a9fac5572", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 170, 0, 17, 256, 224, 0}, // title=Ms. Pac-Man
|
||||
{"220121f771fc4b98", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 10, 20, 270, 234, 0}, // title=Ninja Golf
|
||||
{"74569571a208f8b0", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 245, 0, 12, 256, 224, 0}, // title=One On One
|
||||
{"1a5207870dec6fae", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 120, 0, 12, 256, 220, 0}, // title=Pete Rose Baseball
|
||||
{"33aea1e2b6634a1d", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 175, 0, 15, 256, 226, 0}, // title=Planet Smashers
|
||||
{"584582bb09ee8122", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 210, 39, 15, 320, 230, 0}, // title=Pole Position II
|
||||
{"ac03806cef2558fc", CT_ACTVIS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 1, 16, 259, 234, 0}, // title=Rampage
|
||||
{"383ed9bd1efb9b6c", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 1}, // title=Realsports Baseball
|
||||
{"66ecaafe1b82ae68", CT_NORMAL, POKEY_NONE, TWIN,TWIN, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 5, 13, 270, 234, 0}, // title=Robotron
|
||||
{"980c35ae9625773a", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 8, 18, 265, 234, 0}, // title=Scrapyard Dog
|
||||
{"cbb0746192540a13", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 165, 0, 13, 256, 220, 0}, // title=Summer Games
|
||||
{"cc18e3b37a507c42", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 0, 12, 256, 220, 0}, // title=Super Huey UH-IX
|
||||
{"59b5793bece1c80f", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 130, 0, 12, 256, 220, 0}, // title=Super Skatebordin'
|
||||
{"5c4f752371a523f1", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 150, 0, 12, 256, 220, 0}, // title=Tank Command
|
||||
{"1af475ff6429a160", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 0, 12, 256, 220, 0}, // title=Title Match Pro Wrestling
|
||||
{"c3903ab01a51222a", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 120, 0, 12, 256, 220, 0}, // title=Tomcat F-14 Simulator
|
||||
{"208ef955fa90a298", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Touchdown Football
|
||||
{"8d64763db3100aad", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 8, 320, 234, 1}, // title=Tower Toppler
|
||||
{"427cb05d0a1abb06", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 150, 0, 3, 256, 197, 0}, // title=Water Ski
|
||||
{"3799d72f78dda2ee", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 170, 0, 13, 256, 220, 0}, // title=Winter Games
|
||||
{"90fa275f9f2a65b3", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 170, 0, 13, 256, 220, 0}, // title=Winter Games (alt)
|
||||
{"05fb699db9eef564", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 15, 13, 284, 234, 0}, // title=Xenophobe
|
||||
{"d7dc17379aa25e5a", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 0, 16, 256, 220, 0}, // title=Xevious
|
||||
|
||||
// Prototypes and Hacks
|
||||
{"4332c24e4f3bc72e", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=3D Asteroids
|
||||
{"1745feadabb24e7c", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Impossible Mission
|
||||
{"20660b667df538ec", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 24, 16, 300, 230, 0}, // title=Centipede - Frameless Hack
|
||||
{"8f7eb10ad0bd7547", CT_FRACTALUS, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 180, 0, 12, 256, 220, 0}, // title=Rescue On Fractalus
|
||||
{"06204dadc975be5e", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Gato
|
||||
{"17b3b764d33eae9b", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 0, 20, 256, 234, 0}, // title=Klax (fixed)
|
||||
{"5fb805f2b69820a9", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 0, 20, 256, 234, 0}, // title=Klax
|
||||
{"017066f522908081", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 145, 0, 12, 256, 220, 0}, // title=Missing in Action
|
||||
{"ec206c8db4316eb1", CT_SUPROM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Pit Fighter
|
||||
{"74f0283c566bdee8", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 180, 0, 17, 256, 234, 0}, // title=Plutos XM
|
||||
{"86546808dc60961c", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 180, 0, 17, 256, 234, 0}, // title=Plutos (non-XM)
|
||||
{"1745feadabb24e7c", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 12, 256, 220, 0}, // title=Possible Mission
|
||||
{"b697d9c2d1b9f6cb", CT_SUPROM, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 5, 15, 258, 220, 0}, // title=Sentinel
|
||||
|
||||
// Bob (pacmanplus) Games
|
||||
{"89b8b3df46733e0c", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 165, 0, 12, 256, 220, 0}, // title=Armor Attack II
|
||||
{"eea04359df6770d6", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 165, 0, 12, 256, 220, 0}, // title=Armor Attack II (20230627)
|
||||
{"a65f79ad4a0bbdec", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 0, 17, 256, 230, 0}, // title=Asteroids Deluxe (NTSC) (20071014)
|
||||
{"3d38281ed8a8d8c7", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 245, 30, 9, 320, 210, 0}, // title=Astro Blaster
|
||||
{"55ffe535897c368b", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 245, 30, 9, 320, 210, 0}, // title=Astro Blaster (20230627)
|
||||
{"a51e5df28a0fe8c5", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 32, 9, 320, 213, 0}, // title=Astro Fighter
|
||||
{"8feb090fb1aee5cc", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 32, 9, 320, 213, 0}, // title=Astro Fighter (v1.1)
|
||||
{"7cdfbe37634e7dcd", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 250, 32, 12, 320, 222, 0}, // title=Baby Pac Man
|
||||
{"2b31dfab41dce110", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 250, 32, 12, 320, 222, 0}, // title=Baby Pac Man (20230627)
|
||||
{"34483432b92f565f", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 165, 3, 14, 256, 220, 0}, // title=Bentley Bear's Crystal Quest
|
||||
{"299d31c8e181fdd0", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 5, 256, 203, 0}, // title=Crazy Brix
|
||||
{"2d2fe4da9f1bae10", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 165, 0, 9, 256, 232, 0}, // title=Crazy Otto
|
||||
{"100551363027dc5f", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 165, 0, 9, 256, 232, 0}, // title=Crazy Otto (20230627)
|
||||
{"6287727ab36391a6", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 250, 0, 14, 257, 220, 0}, // title=FailSafe (NTSC) (20100227)
|
||||
{"e7d89669a7f92ec2", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 255, 30, 6, 320, 206, 0}, // title=Frenzy (with Berzerk) (homebrew)
|
||||
{"26031dea7251fb86", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 255, 30, 6, 320, 206, 0}, // title=Frenzy (with Berzerk) (20211025)
|
||||
{"2f4ae1015a345652", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 14, 17, 283, 227, 0}, // title=Galaxian
|
||||
{"686a4e4dde0eca5c", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 14, 17, 283, 227, 0}, // title=Galaxian (v1.1)
|
||||
{"e54edc299e72d22d", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 4, 14, 268, 234, 0}, // title=Jr Pac-Man
|
||||
{"bde3abe40d302d8c", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 4, 14, 268, 234, 0}, // title=Jr Pac-Man (20230627)
|
||||
{"6b8600aabd11f834", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 3, 12, 256, 225, 0}, // title=KC Munchkin
|
||||
{"aa0b9560d6610378", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 3, 12, 256, 225, 0}, // title=KC Munchkin (20230627)
|
||||
{"927edf157f88b8f5", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 3, 12, 256, 225, 0}, // title=KC Munchkin (Alt Movement) (20170409)
|
||||
{"c3f6201d6a9388e8", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 13, 256, 220, 0}, // title=Meteor Shower
|
||||
{"a44241d782ee14b5", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 13, 256, 220, 0}, // title=Meteor Shower (v1.1)
|
||||
{"9ff38ea62004201d", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 30, 20, 320, 234, 0}, // title=Moon Cresta
|
||||
{"a56f26e6d21b2ae4", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 30, 20, 320, 234, 0}, // title=Moon Cresta (v1.1)
|
||||
{"cf007563fe94cacf", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 215, 0, 9, 256, 217, 0}, // title=Ms. Pac-Man (Bob's Enhancements)
|
||||
{"2a17dc5a61be342d", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 5, 16, 265, 230, 0}, // title=Ms Pac-Man 320
|
||||
{"60982f430b762343", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 220, 6, 17, 264, 233, 0}, // title=Pac-Man 320
|
||||
{"5013b69cb05b21a1", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 210, 10, 11, 281, 231, 0}, // title=Pac-Man Collection (homebrew)
|
||||
{"6a432fd1e9d42a29", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 210, 10, 11, 281, 231, 0}, // title=Pac-Man Collection - Ultimate Edition (POKEY) (4000)
|
||||
{"ce1cb2f5d2238449", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 210, 10, 11, 281, 231, 0}, // title=Pac-Man Collection - Ultimate Edition (POKEY) (4000)
|
||||
{"200ef9c7b36afd3b", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_YES, 210, 10, 11, 281, 231, 0}, // title=Pac-Man Collection - Remastered (TIA)
|
||||
{"f2512870a8abc82d", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 9, 10, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Newest
|
||||
{"a59d362e3a391ff1", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 220, 9, 10, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - Older
|
||||
{"1330d23ebad9b5de", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 220, 9, 10, 278, 221, 0}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew) - PMC_XM Newest
|
||||
{"2b60de20a55056a1", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 11, 17, 279, 233, 0}, // title=Pac-Man Collection 40th - Short Mazes (2022) - Newest
|
||||
{"c80edcd555cd3d81", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 11, 17, 279, 233, 0}, // title=Pac-Man Collection 40th - Short Mazes (2022)
|
||||
{"39dc7f6f39f9b3e3", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 200, 9, 10, 278, 221, 0}, // title=Pac-Man Collection - 40th Anniversary Edition (20230627)
|
||||
{"2686f20449c339f7", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 200, 11, 17, 279, 233, 0}, // title=Pac-Man Collection - 40th Anniversary Edition (Short Mazes) (20230627)
|
||||
{"2b51ebf2f371d079", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 10, 18, 271, 234, 0}, // title=Pac-Man - Energy Drink Edition (20230707)
|
||||
{"d0bf3b841ad4bbd3", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 200, 10, 12, 274, 233, 0}, // title=Pac-Man Plus 320
|
||||
{"43525a0405184875", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 17, 256, 233, 0}, // title=Rip-Off
|
||||
{"803743fe18600f29", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 17, 256, 233, 0}, // title=Rip-Off (20230627)
|
||||
{"a3a85e507d6f7189", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 250, 30, 5, 320, 205, 0}, // title=Scramble (homebrew)
|
||||
{"31b20a4710e69130", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 250, 30, 5, 320, 205, 0}, // title=Scramble (20230627)
|
||||
{"771cb4609347657f", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 200, 0, 12, 256, 220, 0}, // title=Space Duel (homebrew)
|
||||
{"6adf79558a3d7f5b", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 165, 30, 8, 320, 210, 0}, // title=Space Invaders (Homebrew)
|
||||
{"6a898d52ef050cdb", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 165, 30, 8, 320, 210, 0}, // title=Space Invaders (v1.1)
|
||||
{"7ab539bb0e99e1e5", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 0, 5, 256, 225, 0}, // title=Super Pac-Man
|
||||
{"88b9de0eba37ba51", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 205, 0, 5, 256, 225, 0}, // title=Super Pac-Man (20230627)
|
||||
{"79df20ee86a989e6", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 9, 18, 282, 230, 0}, // title=UniWarS
|
||||
{"0db69825c81171e6", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 9, 18, 282, 230, 0}, // title=UniWarS (v1.1)
|
||||
{"f41f651417c23410", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 240, 26, 12, 320, 225, 0}, // title=Super Cobra
|
||||
|
||||
{"fd9353d42cca5f81", CT_SUPRAMX2,POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 190, 0, 6, 256, 203, 1}, // title=1942 (Standard Banking RAM)
|
||||
{"e1b290ee690c0cd6", CT_SUPRAMX2,POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 190, 0, 6, 256, 203, 1}, // title=1942 (Standard Banking RAM)
|
||||
{"0fec9c1f5973c7a1", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 190, 0, 6, 256, 203, 1}, // title=1942 (Dragonfly Banking RAM)
|
||||
{"6f157f421c7ed5d9", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 22, 14, 299, 230, 0}, // title=2048 (RC1a) (20211113)
|
||||
{"a837a34f540fd137", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 14, 16, 286, 234, 0}, // title=7iX (20220305)
|
||||
{"ff056f2858f14fc4", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 3, 15, 261, 234, 0}, // title=A Roach In Space - Part II - Electric Bugaloo (20201119)
|
||||
{"d99bff88cd3cce19", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
|
||||
{"212ee2a6e66d8bb7", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
|
||||
{"e1da4c3ea0d26ae0", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 9, 256, 200, 0}, // title=Arkanoid 78b Demo (purposely set HSC to false - game HSC is buggy)
|
||||
{"0d05659a7d0eef02", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 1, 16, 268, 234, 0}, // title=ARTI Public Demo
|
||||
{"4a8a22cff154f479", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 120, 0, 7, 256, 220, 0}, // title=Boom!
|
||||
{"9fa7743a016c9b70", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 27, 256, 234, 0}, // title=BonQ (Final Atariage)
|
||||
{"78b1061d651ef806", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 135, 0, 16, 256, 234, 0}, // title=Beef Drop (Final Atariage)
|
||||
{"b11b1a2bae8a1d0c", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 125, 3, 13, 264, 227, 0}, // title=Bernie and the Cubic Conundrum (Alpha 10)
|
||||
{"a34cd425d0c087d0", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 125, 6, 16, 264, 233, 0}, // title=Bernie and the Tower of Doom (RC1) (Demo)
|
||||
{"000b5888d2489f7e", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 0, 12, 256, 223, 0}, // title=Cannon in D for Defense (demo 03)
|
||||
{"825c03c049306c16", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 125, 0, 16, 260, 234, 0}, // title=Cartesian Chaos (v11) (20221218)
|
||||
{"a4b5d742860beb25", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 120, 8, 19, 269, 233, 0}, // title=Chase (20201231)
|
||||
{"0c2f248a1ae9bfd1", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 14, 256, 234, 0}, // title=Danger Zone (RC-4C) (NTSC Demo) (20201231)
|
||||
{"fab7b59dd580dce0", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 2, 17, 260, 229, 0}, // title=Death Merchant (v1_30)
|
||||
{"dd1cfc933d2bfacc", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 185, 0, 12, 256, 210, 0}, // title=Donkey Kong PK-XM (NTSC) (Demo) (v1.2)
|
||||
{"c3107d3e3e17d67e", CT_SUPLRG, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 185, 0, 20, 256, 223, 0}, // title=Donkey Kong XM DEMO
|
||||
{"312363c7691fa51e", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 180, 0, 17, 256, 216, 0}, // title=Donkey Kong Remix DEMO
|
||||
{"77164df89ae49b4d", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 125, 0, 16, 256, 234, 0}, // title=Dragon's Descent (20210731)
|
||||
{"8c2798f929a43317", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 125, 6, 15, 256, 232, 0}, // title=Dragon's Havoc (Demo Dec 2022)
|
||||
{"7b7825ca2c79148f", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 125, 6, 15, 256, 232, 0}, // title=Dragon's Cache (20210207)
|
||||
{"a9f29004412621f2", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 16, 256, 230, 0}, // title=Draker Quest II
|
||||
{"fab1290f9a4c4f2b", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 120, 0, 17, 256, 230, 0}, // title=Draker Quest (Beta 4)
|
||||
{"b3143adbbb7d7d18", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 9, 256, 231, 0}, // title=Dungeon Stalker (20151022)
|
||||
{"a44e8b7b7881beb0", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 135, 0, 16, 256, 234, 0}, // title=E.X.O. (RC Demo A)
|
||||
{"6053233cb59c0b4c", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 210, 34, 4, 320, 216, 0}, // title=Froggie (NTSC) (Final Release)
|
||||
{"9daaac9b25783a7e", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 16, 256, 224, 0}, // title=Frogus (20221020)
|
||||
{"c2e131a091ceed2e", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 15, 256, 234, 0}, // title=Game of the Bear - Polar Opposites (RC1) (20230211)
|
||||
{"e443f7fb5be3283d", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 13, 12, 280, 234, 0}, // title=GoSub
|
||||
{"1e21bf1d9d7b3c0c", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 160, 0, 11, 256, 220, 0}, // title=Graze Suit Alpha (20170910)
|
||||
{"1c9deabc48f07d1b", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 115, 0, 12, 256, 220, 0}, // title=Keystone Koppers (Demo Dec 22)
|
||||
{"d41d8cd98f00b204", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 115, 0, 12, 256, 220, 0}, // title=Keystone Koppers (RC4 Demo)
|
||||
{"1d47c3802135d864", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 130, 0, 12, 256, 233, 0}, // title=Knight Guy On Board - 30 Squares Of Fate (20210116)
|
||||
{"0916973898e3b6b8", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 130, 0, 12, 256, 233, 0}, // title=Knight Guy On Board - 30 Squares Of Fate (Demo 3)
|
||||
{"33dbb58f9ee73e9f", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 130, 0, 12, 256, 233, 0}, // title=Knight Guy In Low Res World - Castle Days (RC 01-1)
|
||||
{"3ec728e116017be8", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 130, 0, 12, 256, 233, 0}, // title=Knight Guy - Quest For Something (20210423)
|
||||
{"7abd9e0a6321e813", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_B, DIFF_B, NTSC, HSC_NO, 130, 0, 12, 256, 233, 0}, // title=Knight Guy - In Another Castle (RC1b)
|
||||
{"271864e0978278a3", CT_SUPCAR, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 7, 256, 201, 0}, // title=Legend of Silverpeak (1.01)
|
||||
{"7abd9e0a6321e813", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 135, 6, 16, 264, 234, 0}, // title=Lunar Patrol (v83) (20241231) (2354A1FF)
|
||||
{"23ac803eabfb8c61", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 12, 256, 234, 0}, // title=Lyra the Tenrec (20240104)
|
||||
{"181a9978d9da7a7e", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 17, 320, 234, 0}, // title=Merlain
|
||||
{"3f80432f156088bf", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 14, 256, 220, 0}, // title=Millie And Molly (Demo) (POKEY 450) (20230305)
|
||||
{"1c860298a8966cc8", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 14, 256, 220, 0}, // title=Monster Maze (20220306)
|
||||
{"d1b56eae7227c12d", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 0, 17, 256, 224, 0}, // title=Morf (20220314)
|
||||
{"ac5c99ac01c96ad9", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 130, 0, 16, 256, 234, 0}, // title=Ninjish Guy - Perilous Island (20211107)
|
||||
{"3d9c52142f9e53f5", CT_SUPLRG, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 17, 256, 234, 0}, // title=Oozy The Goo - Gaiden (20231001)
|
||||
{"6ac5a7f8b6a3198e", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 125, 2, 17, 260, 234, 0}, // title=PentaGo (Demo) (20230422)
|
||||
{"a662862f20362fc5", CT_BANKSHALT,POKEY_AT_800,SNES,JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 10, 256, 214, 0}, // title=Attack of the Petscii Robots (Demo) (POKEY 800)
|
||||
{"0254afa887fcfc8c", CT_SUPRAM, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 16, 17, 289, 220, 0}, // title=Plumb Luck DX (RC2) (20230410)
|
||||
{"61e6a16889b62216", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 17, 256, 220, 0}, // title=Popeye 2.40 Demo
|
||||
{"fab49206f4b041fa", CT_SUPLRG, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 140, 0, 17, 256, 220, 0}, // title=Popeye 2.40 j7800 Demo
|
||||
{"b6561537290e6e25", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 12, 256, 220, 0}, // title=Robbo (20160513)
|
||||
{"fc525819ec2bdc4a", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 140, 0, 11, 256, 217, 0}, // title=Robots Rumble (20220217)
|
||||
{"9bd70c06d3386f76", CT_SUPRAM, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 12, 256, 220, 0}, // title=Serpentine (20161029)
|
||||
{"96f69b85e0b43bbe", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 120, 0, 12, 256, 233, 0}, // title=Sick Pickles (20171202)
|
||||
{"40567f50c569a60c", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 16, 256, 230, 0}, // title=Slide Boy in Maze Land (RC1) (20210515)
|
||||
{"91f4cb1f642ff1de", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 110, 0, 16, 256, 230, 0}, // title=Space Peril (NTSC) (v8) (20210907)
|
||||
{"19844117863cd38d", CT_SUPLRG, POKEY_NONE, SOTA,SOTA, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 31, 17, 320, 230, 0}, // title=Spire of the Ancients (NTSC) (20201223)
|
||||
{"81cee326b99d6831", CT_NORMAL, POKEY_AT_4000, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 200, 0, 13, 256, 220, 0}, // title=Super Circus Atari Age (NTSC) (Joystick) (POKEY 4000)
|
||||
{"02508e6df5e173b4", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 200, 0, 13, 256, 220, 0}, // title=Super Circus Atari Age (NTSC) (Joystick) (POKEY 0450)
|
||||
{"a60e4b608505d1fb", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 16, 256, 230, 0}, // title=Time Salvo
|
||||
{"ff825fcbed9bf699", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 120, 0, 17, 256, 220, 0}, // title=Touchdown Challenge (v2_21) (20230225)
|
||||
{"0d7e2674d802b412", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_NO, 120, 0, 13, 256, 233, 0}, // title=Tunnels of Hyperion
|
||||
{"f5150c0fc1948832", CT_NORMAL, POKEY_AT_450, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 160, 0, 12, 256, 240, 0}, // title=7800 Utility Cart
|
||||
{"846751861993b907", CT_NORMAL, POKEY_NONE, JOY, JOY, DIFF_A, DIFF_A, NTSC, HSC_YES, 130, 0, 16, 256, 231, 0}, // title=Wizards Dungeon (20211111)
|
||||
|
||||
{"",CT_NORMAL,0,0,0,0,0,0,0,0,0,0,0},
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool database_Load(byte *digest)
|
||||
|
||||
|
||||
NameMap_t NameMap[] =
|
||||
{
|
||||
bool bFound = false;
|
||||
uint i;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// This happens AFTER The rom is loaded and the header info (if any) has
|
||||
// been read out. Here we can adjust based on the hash table above... which
|
||||
// is mainly used for headerless roms and a few special cases were we want
|
||||
// to correct the Y-offsets to make the game well centered/scaled on screen.
|
||||
// -------------------------------------------------------------------------
|
||||
if(database_enabled)
|
||||
{
|
||||
/* Look up mapper in game list by md5sum */
|
||||
for(i = 0; strlen(game_list[i].digest); i++)
|
||||
{
|
||||
if (!strcmp(game_list[i].digest,(char *) digest))
|
||||
{
|
||||
cartridge_type = game_list[i].cardtype;
|
||||
cartridge_pokey = game_list[i].pokeyType;
|
||||
cartridge_controller[0] = game_list[i].cardctrl1;
|
||||
cartridge_controller[1] = game_list[i].cardctrl2;
|
||||
cartridge_region = game_list[i].cardregion;
|
||||
cartridge_steals_cycles = game_list[i].steals_cycles;
|
||||
cartridge_uses_wsync = game_list[i].uses_wsync;
|
||||
cartridge_hsc_enabled = game_list[i].hsc;
|
||||
cartridge_xOffset = game_list[i].xOffset;
|
||||
cartridge_yOffset = game_list[i].yOffset;
|
||||
cartridge_xScale = game_list[i].xScale;
|
||||
cartridge_yScale = game_list[i].yScale;
|
||||
cartridge_diff1 = game_list[i].diff1;
|
||||
cartridge_diff2 = game_list[i].diff2;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{"POPEYE", "POPEYE", "61e6a16889b62216"},
|
||||
{"EXO", "EXO", "a44e8b7b7881beb0"},
|
||||
{"KOPPERS", "KOPPERS", "d41d8cd98f00b204"},
|
||||
{"TIME", "SALVO", "a60e4b608505d1fb"},
|
||||
{"CHRISTMAS", "SALVO", "a60e4b608505d1fb"},
|
||||
{"MERLAIN", "MERLAIN", "181a9978d9da7a7e"},
|
||||
{"TOUCHDOWN", "CHALLENGE", "ff825fcbed9bf699"},
|
||||
{"OOZY", "GAIDEN", "3d9c52142f9e53f5"},
|
||||
{"MILLIE", "MOLLY", "3f80432f156088bf"},
|
||||
{"SILVERPEAK", "SILVERPEAK", "271864e0978278a3"},
|
||||
{"LUNAR", "PATROL", "7abd9e0a6321e813"},
|
||||
{"ATTACK", "PETSCII", "a662862f20362fc5"},
|
||||
{"KNIGHT", "BOARD", "0916973898e3b6b8"},
|
||||
{"KNIGHT", "WORLD", "33dbb58f9ee73e9f"},
|
||||
{"KNIGHT", "SOMETHING", "3ec728e116017be8"},
|
||||
{"KNIGHT", "ANOTHER", "7abd9e0a6321e813"},
|
||||
{"DRAGON", "DESCENT", "77164df89ae49b4d"},
|
||||
{"DRAGON", "HAVOC", "8c2798f929a43317"},
|
||||
{"DRAGON", "CACHE", "7b7825ca2c79148f"},
|
||||
{"ARKANOID", "ARKANOID", "d99bff88cd3cce19"},
|
||||
{"ARTI", "ATRI", "0d05659a7d0eef02"},
|
||||
{"CANNON", "DEFENSE", "000b5888d2489f7e"},
|
||||
{"1942", "1942", "fd9353d42cca5f81"},
|
||||
{"WIZARD", "DUNGEON", "846751861993b907"},
|
||||
{"UTILITY", "CART", "f5150c0fc1948832"},
|
||||
{"BONQ", "BONQ", "9fa7743a016c9b70"},
|
||||
{"BEEF", "DROP", "78b1061d651ef806"},
|
||||
{"BERNIE", "CUBIC", "b11b1a2bae8a1d0c"},
|
||||
{"BERNIE", "TOWER", "a34cd425d0c087d0"},
|
||||
{"DEATH", "MERCHANT", "fab7b59dd580dce0"},
|
||||
{"TUNNELS", "HYPERION", "0d7e2674d802b412"},
|
||||
{"SLIDE", "MAZE", "40567f50c569a60c"},
|
||||
{"CARTESIAN", "CHAOS", "825c03c049306c16"},
|
||||
{"DANGER", "ZONE", "0c2f248a1ae9bfd1"},
|
||||
{"SCRAMBLE", "SCRAMBLE", "a3a85e507d6f7189"},
|
||||
{"KLAX", "KLAX", "17b3b764d33eae9b"},
|
||||
{"PENTAGO", "PENTAGO", "6ac5a7f8b6a3198e"},
|
||||
|
||||
|
||||
/* If we didn't find a definitive md5 match above, look up game by cart title in the .A78 header */
|
||||
if (!bFound)
|
||||
{"","",""}
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// This happens AFTER The rom is loaded and the header info (if any) has
|
||||
// been read out. Here we can adjust based on the hash table above... which
|
||||
// is mainly used for headerless roms and a few special cases were we want
|
||||
// to correct the Y-offsets to make the game well centered/scaled on screen.
|
||||
// -------------------------------------------------------------------------
|
||||
bool database_Load(byte * digest)
|
||||
{
|
||||
extern u8 bNoDatabase;
|
||||
bool bFound = false;
|
||||
uint16 i;
|
||||
|
||||
// Uppercase the filename... to make searching easier.
|
||||
for(int j = 0; j < strlen(cartridge_filename); j++) cartridge_filename[j] = toupper(cartridge_filename[j]);
|
||||
|
||||
// See if we've been asked to skip the internal database
|
||||
if(!bNoDatabase)
|
||||
{
|
||||
for(i = 0; strlen(game_list[i].header_name); i++)
|
||||
{
|
||||
if (cartridge_region == NTSC)
|
||||
// --------------------------------------------------------------------------------------
|
||||
// First see if we've got a match in our external A7800DS.DAT configuration database...
|
||||
// --------------------------------------------------------------------------------------
|
||||
for(i = 0; i < MAX_CONFIGS; i++)
|
||||
{
|
||||
if ( (!strcmp(game_list[i].header_name,(char *) cartridge_title)) ||
|
||||
(strstr((char *) cartridge_filename, game_list[i].header_name) != NULL) )
|
||||
{
|
||||
cartridge_type = game_list[i].cardtype;
|
||||
cartridge_pokey = game_list[i].pokeyType;
|
||||
cartridge_controller[0] = game_list[i].cardctrl1;
|
||||
cartridge_controller[1] = game_list[i].cardctrl2;
|
||||
cartridge_region = game_list[i].cardregion;
|
||||
cartridge_steals_cycles = game_list[i].steals_cycles;
|
||||
cartridge_uses_wsync = game_list[i].uses_wsync;
|
||||
cartridge_hsc_enabled = game_list[i].hsc;
|
||||
cartridge_xOffset = game_list[i].xOffset;
|
||||
cartridge_yOffset = game_list[i].yOffset;
|
||||
cartridge_xScale = game_list[i].xScale;
|
||||
cartridge_yScale = game_list[i].yScale;
|
||||
cartridge_diff1 = game_list[i].diff1;
|
||||
cartridge_diff2 = game_list[i].diff2;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
if(!strncmp(allConfigs.cart[i].half_digest, (char *) digest, 16))
|
||||
{
|
||||
memcpy( & myCartInfo, & allConfigs.cart[i], sizeof(myCartInfo));
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// If we didn't find it in the config database, we can look in the internal database table...
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
if(!bFound)
|
||||
{
|
||||
/* Look up mapper in game list by md5sum */
|
||||
for(i = 0; strlen(game_list[i].half_digest); i++)
|
||||
{
|
||||
if(!strncmp(game_list[i].half_digest, (char *) digest, 16))
|
||||
{
|
||||
memcpy( & myCartInfo, & game_list[i], sizeof(myCartInfo));
|
||||
if(!isDSiMode()) myCartInfo.frameSkip = ((cartridge_size <= (48 * 1024)) ? FRAMESKIP_MEDIUM : FRAMESKIP_AGGRESSIVE); // Older DS-Lite/Phat needs help
|
||||
myCartInfo.palette = 1; // Force this if not specifically found by md5
|
||||
myCartInfo.xJiggle = 64;
|
||||
myCartInfo.yJiggle = 16;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
// If we didn't find a definitive md5 match above, look up game by name in our name mapping table.
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
if(!bFound)
|
||||
{
|
||||
for(int k = 0; strlen(NameMap[k].name1); k++)
|
||||
{
|
||||
if(myCartInfo.region == NTSC)
|
||||
{
|
||||
if((strstr(cartridge_filename, NameMap[k].name1)) && (strstr(cartridge_filename, NameMap[k].name2))) // If both names are found in the filename...
|
||||
{
|
||||
/* Look up mapper in game list by md5sum from the Name Mapper table */
|
||||
for(i = 0; strlen(game_list[i].half_digest); i++)
|
||||
{
|
||||
if(!strncmp(game_list[i].half_digest, (char *) NameMap[k].half_digest, 16))
|
||||
{
|
||||
memcpy( & myCartInfo, & game_list[i], sizeof(myCartInfo));
|
||||
if(!isDSiMode()) myCartInfo.frameSkip = ((cartridge_size <= (48 * 1024)) ? FRAMESKIP_MEDIUM : FRAMESKIP_AGGRESSIVE); // Older DS-Lite/Phat needs help
|
||||
myCartInfo.palette = 1; // Force this if not specifically found by md5
|
||||
myCartInfo.xJiggle = 64;
|
||||
myCartInfo.yJiggle = 16;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Default scaling options below if not found... these are close enough...
|
||||
if (!bFound)
|
||||
{
|
||||
cartridge_xOffset = 0;
|
||||
cartridge_yOffset = 22;
|
||||
cartridge_xScale = 256;
|
||||
cartridge_yScale = 220;
|
||||
cartridge_diff1 = DIFF_A;
|
||||
cartridge_diff2 = DIFF_A;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
// No matter what... override for Tower Toppler to make it playable...
|
||||
if(strcmp((char *) digest, (char *) "8d64763db3100aadc552db5e6868506a") == 0) // Tower Toppler
|
||||
{
|
||||
use_composite_filtering = 76;
|
||||
myCartInfo.frameSkip = FRAMESKIP_AGGRESSIVE; // It's the only way we stand a chance.
|
||||
myCartInfo.cardctrl1 = SOTA;
|
||||
myCartInfo.xOffset = 32;
|
||||
myCartInfo.yOffset = 8;
|
||||
myCartInfo.xScale = 320;
|
||||
myCartInfo.yScale = 234;
|
||||
bFound = 1;
|
||||
}
|
||||
else if(strcmp((char *) digest, (char *) "f5150c0fc1948832211e57852abb0c6e") == 0) // 7800 Utility Cart
|
||||
{
|
||||
use_composite_filtering = 1;
|
||||
bFound = 1;
|
||||
}
|
||||
// Override for Jinks to enable composite filtering
|
||||
else if(strcmp((char *) digest, (char *) "045fd12050b7f2b842d5970f2414e912") == 0) // Jinks
|
||||
{
|
||||
use_composite_filtering = 1;
|
||||
bFound = 1;
|
||||
}
|
||||
else use_composite_filtering = 0;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Default scaling options below if not found... these are close enough...
|
||||
// We can make some educated guesses on cart and frameskip...
|
||||
// --------------------------------------------------------------------------
|
||||
if(!bFound)
|
||||
{
|
||||
strncpy(myCartInfo.half_digest, (char *) digest, 16);
|
||||
myCartInfo.half_digest[16] = 0;
|
||||
myCartInfo.xOffset = 0;
|
||||
myCartInfo.yOffset = 13;
|
||||
myCartInfo.xScale = 256;
|
||||
myCartInfo.yScale = 220;
|
||||
myCartInfo.diff1 = DIFF_A;
|
||||
myCartInfo.diff2 = DIFF_A;
|
||||
myCartInfo.xButton = KEY_MAP_DEFAULT;
|
||||
myCartInfo.yButton = KEY_MAP_DEFAULT;
|
||||
myCartInfo.spare2 = 0;
|
||||
myCartInfo.spare3 = 0;
|
||||
myCartInfo.spare4 = 1;
|
||||
myCartInfo.spare5 = 0;
|
||||
myCartInfo.palette = 1;
|
||||
myCartInfo.xJiggle = 64;
|
||||
myCartInfo.yJiggle = 16;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// If the game has no .a78 header, do our best to guess these...
|
||||
// -------------------------------------------------------------------
|
||||
if(myCartInfo.hasHeader == false)
|
||||
{
|
||||
myCartInfo.region = NTSC;
|
||||
if(cartridge_size == (144 * 1024)) myCartInfo.cardtype = CT_SUPLRG;
|
||||
else myCartInfo.cardtype = (cartridge_size <= (52 * 1024)) ? CT_NORMAL : CT_SUPROM;
|
||||
myCartInfo.pokeyType = POKEY_NONE;
|
||||
myCartInfo.cardctrl1 = JOY;
|
||||
myCartInfo.cardctrl2 = JOY;
|
||||
myCartInfo.hsc = false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Do our best guess as to whether we should frameskip...
|
||||
// --------------------------------------------------------
|
||||
if(isDSiMode()) // DSi can handle most games in full framerate... default to disable frameskip for the DSi
|
||||
{
|
||||
myCartInfo.frameSkip = FRAMESKIP_DISABLE;
|
||||
}
|
||||
else // DS-Lite defaults to some level of frame skipping
|
||||
{
|
||||
myCartInfo.frameSkip = ((cartridge_size <= (48 * 1024)) ? FRAMESKIP_MEDIUM : FRAMESKIP_AGGRESSIVE); // Non-banked carts get light frameskip... otherwise agressive
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly - use the internal database to always try and find a BIOS timeout value... we don't let the user override this one...
|
||||
myCartInfo.biosTimeout = 160;
|
||||
bFound = 0;
|
||||
for(i = 0; strlen(game_list[i].half_digest); i++) // Search through entire internal database...
|
||||
{
|
||||
if(!strncmp(game_list[i].half_digest, (char *) digest, 16)) // Search by md5sum
|
||||
{
|
||||
myCartInfo.biosTimeout = game_list[i].biosTimeout;
|
||||
bFound = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!bFound) // And if not found - search by name to find a reasonable bios timeout value
|
||||
{
|
||||
for(int k = 0; strlen(NameMap[k].name1); k++)
|
||||
{
|
||||
if(myCartInfo.region == NTSC)
|
||||
{
|
||||
if((strstr(cartridge_filename, NameMap[k].name1)) && (strstr(cartridge_filename, NameMap[k].name2))) // If both names are found in the filename...
|
||||
{
|
||||
/* Look up bios timeout in game list by md5sum from the Name Mapper table */
|
||||
for(i = 0; strlen(game_list[i].half_digest); i++)
|
||||
{
|
||||
if(!strncmp(game_list[i].half_digest, (char *) NameMap[k].half_digest, 16))
|
||||
{
|
||||
myCartInfo.biosTimeout = game_list[i].biosTimeout;
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -27,9 +27,61 @@
|
|||
|
||||
#include "Cartridge.h"
|
||||
|
||||
typedef struct {
|
||||
char half_digest[17];
|
||||
u8 cardtype;
|
||||
u8 pokeyType;
|
||||
u8 cardctrl1;
|
||||
u8 cardctrl2;
|
||||
u8 diff1;
|
||||
u8 diff2;
|
||||
u8 region;
|
||||
u8 hsc;
|
||||
u8 biosTimeout;
|
||||
s16 xOffset;
|
||||
s16 yOffset;
|
||||
s16 xScale;
|
||||
s16 yScale;
|
||||
u8 frameSkip;
|
||||
u8 spare0;
|
||||
u8 spare1;
|
||||
u8 hasHeader;
|
||||
u8 palette;
|
||||
u8 xJiggle;
|
||||
u8 yJiggle;
|
||||
u8 xButton;
|
||||
u8 yButton;
|
||||
u8 spare2;
|
||||
u8 spare3;
|
||||
u8 spare4;
|
||||
u8 spare5;
|
||||
u8 spare6;
|
||||
u8 spare7;
|
||||
} Database_Entry;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *name1;
|
||||
char *name2;
|
||||
char *half_digest;
|
||||
} NameMap_t;
|
||||
|
||||
extern Database_Entry myCartInfo;
|
||||
|
||||
#define KEY_MAP_DEFAULT 0
|
||||
#define KEY_MAP_PANUP 1
|
||||
#define KEY_MAP_PANDN 2
|
||||
#define KEY_MAP_JOYUP 3
|
||||
#define KEY_MAP_JOYDN 4
|
||||
#define KEY_MAP_JOYLEFT 5
|
||||
#define KEY_MAP_JOYRIGHT 6
|
||||
#define KEY_MAP_JOYB1 7
|
||||
#define KEY_MAP_JOYB2 8
|
||||
#define KEY_MAP_PAUSE 9
|
||||
|
||||
|
||||
extern void database_Initialize( );
|
||||
extern bool database_Load(byte *digest);
|
||||
extern bool database_enabled;
|
||||
//extern std::string database_filename;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "Hash.h"
|
||||
#include "../printf.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Step1
|
||||
|
@ -231,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
@ -21,75 +21,220 @@
|
|||
// 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>
|
||||
#include <ctype.h>
|
||||
#include "HighScore.h"
|
||||
#include "Cartridge.h"
|
||||
#include "Database.h"
|
||||
|
||||
// The memory location of the high score cartridge SRAM
|
||||
#define HS_SRAM_START 0x1000
|
||||
// The size of the high score cartridge SRAM
|
||||
#define HS_SRAM_SIZE 2048
|
||||
#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
|
||||
|
||||
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)
|
||||
byte high_score_cart_loaded = false; // Flips to true if the High Score Cart is loaded in memory
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// 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 (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,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static byte high_score_cart_loaded = false;
|
||||
static u32 last_chksum = 0xFFFFEEEF;
|
||||
|
||||
/*
|
||||
* Saves the high score cartridge SRAM
|
||||
*
|
||||
* return Whether the save was successful
|
||||
* return Whether the save was successful (false if game is not supporting HSC)
|
||||
*/
|
||||
bool cartridge_SaveHighScoreSram(void)
|
||||
{
|
||||
bool status = false;
|
||||
byte sram[HS_SRAM_SIZE];
|
||||
word retries = 3;
|
||||
if(!high_score_cart_loaded || !cartridge_hsc_enabled)
|
||||
static char szName[256+4];
|
||||
static void make_hsc_name(void)
|
||||
{
|
||||
// Init HSC filename is same as base filename with .hsc
|
||||
DIR* dir = opendir("sav");
|
||||
if (dir) closedir(dir); // Directory exists... close it out and move on.
|
||||
else mkdir("sav", 0777); // Otherwise create the directory...
|
||||
sprintf(szName,"sav/%s", cartridge_filename);
|
||||
|
||||
int len = strlen(szName);
|
||||
szName[len-3] = 'h';
|
||||
szName[len-2] = 's';
|
||||
szName[len-1] = 'c';
|
||||
szName[len-0] = 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Write the full 2K of HSC - a bit wasteful for a single game but we've got plenty
|
||||
// of space and it turns out to be more flexibile for each game to have their own HSC.
|
||||
// ------------------------------------------------------------------------------------
|
||||
bool cartridge_SaveHighScoreSram(void)
|
||||
{
|
||||
if(!high_score_cart_loaded || !myCartInfo.hsc)
|
||||
{
|
||||
// If we didn't load the high score cartridge, or don't have an HSC enabled cart: don't save.
|
||||
return false;
|
||||
return false; // If we didn't load the high score cartridge, or don't have an HSC enabled cart: don't save.
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// We are being fairly paranoid here mainly because there are games that corrupt the SRAM area
|
||||
// of the high score cart... XENOPHOBE is one. The Donkey Kong XM Homebrew is another. So we
|
||||
// want to make sure we aren't saving crap out - this is fairly robust ... so far...
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
while (status == false)
|
||||
// Make sure something actually changed before writing...
|
||||
if (memcmp(high_score_sram, memory_ram+HS_SRAM_START, HS_SRAM_SIZE) != 0)
|
||||
{
|
||||
u32 chksum = 0;
|
||||
for( uint i = 0; i < HS_SRAM_SIZE; i++ )
|
||||
{
|
||||
sram[i] = memory_ram[HS_SRAM_START+i];
|
||||
chksum += sram[i];
|
||||
}
|
||||
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 sure there is something different/worth saving...
|
||||
// ------------------------------------------------------------
|
||||
if ((chksum != last_chksum) && (chksum != 0))
|
||||
{
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
// Check to make sure the High Score Cart "Magic Numbers" are right... otherwise corrupt and don't save...
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
if ((sram[2] == 0x68) && (sram[3] == 0x83) && (sram[4] == 0xaa) && (sram[5] == 0x55) && (sram[6] == 0x9c))
|
||||
{
|
||||
last_chksum = chksum;
|
||||
FILE* file = fopen("A7800DS.sram", "wb+");
|
||||
if( file != NULL )
|
||||
{
|
||||
if( fwrite( sram, 1, HS_SRAM_SIZE, file ) != HS_SRAM_SIZE )
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
fflush(file);
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (--retries == 0) break;
|
||||
// Write out the .hsc file
|
||||
FILE *handle = fopen(szName, "wb");
|
||||
if (handle != NULL)
|
||||
{
|
||||
fwrite(high_score_sram, HS_SRAM_SIZE, 1, handle);
|
||||
fclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
return true; // We at least made the attempt to write out the .hsc save file
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -98,36 +243,36 @@ bool cartridge_SaveHighScoreSram(void)
|
|||
* return Whether the load was successful
|
||||
*/
|
||||
static bool cartridge_LoadHighScoreSram(void)
|
||||
{
|
||||
bool status = false;
|
||||
byte sram[HS_SRAM_SIZE];
|
||||
word retries=3;
|
||||
|
||||
while (status == false)
|
||||
{
|
||||
if(!high_score_cart_loaded || !myCartInfo.hsc)
|
||||
{
|
||||
FILE* file = fopen("A7800DS.sram", "rb" );
|
||||
if( file == NULL )
|
||||
{
|
||||
status = false;
|
||||
}
|
||||
return false; // If we didn't load the high score cartridge, or don't have an HSC enabled cart: don't save.
|
||||
}
|
||||
|
||||
if( fread( sram, 1, HS_SRAM_SIZE, file ) == HS_SRAM_SIZE )
|
||||
{
|
||||
fclose( file );
|
||||
last_chksum = 0;
|
||||
for( uint i = 0; i < HS_SRAM_SIZE; i++ )
|
||||
{
|
||||
memory_Write( HS_SRAM_START + i, sram[i] );
|
||||
last_chksum += sram[i];
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
if (--retries == 0) break;
|
||||
make_hsc_name(); // HSC filename is same as base filename with .hsc extension
|
||||
|
||||
// Read back the .hsc file
|
||||
FILE *handle = fopen(szName, "rb");
|
||||
if (handle != NULL)
|
||||
{
|
||||
fread(high_score_sram, HS_SRAM_SIZE, 1, handle);
|
||||
fclose(handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No .hsc file was available... so set the SRAM to a known good init value
|
||||
memcpy(high_score_sram, A7800DS_00_sram, HS_SRAM_SIZE);
|
||||
}
|
||||
|
||||
// Copy from SRAM buffer to main memory for use by the game
|
||||
for(uint i = 0; i < HS_SRAM_SIZE; i++)
|
||||
{
|
||||
memory_Write(HS_SRAM_START + i, high_score_sram[i]);
|
||||
}
|
||||
|
||||
return status;
|
||||
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!
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -135,33 +280,37 @@ static bool cartridge_LoadHighScoreSram(void)
|
|||
*
|
||||
* return Whether the load was successful
|
||||
*/
|
||||
#define HSC_CART_ROM_SIZE 4096
|
||||
byte high_score_buffer[HSC_CART_ROM_SIZE];
|
||||
bool cartridge_LoadHighScoreCart(void)
|
||||
bool cartridge_LoadHighScoreCart(void)
|
||||
{
|
||||
if( !cartridge_hsc_enabled || cartridge_region != 0 )
|
||||
if( !myCartInfo.hsc || myCartInfo.region != 0 )
|
||||
{
|
||||
// Only load the cart if it is enabled and the region is NTSC
|
||||
return false;
|
||||
return false; // Only load the cart if it is enabled and the region is NTSC
|
||||
}
|
||||
|
||||
FILE* file = fopen("highscore.rom", "rb" );
|
||||
|
||||
if( file != NULL )
|
||||
// If we don't find it in the current directory, always try /roms/bios and /data/bios
|
||||
if (file == NULL) file = fopen("/roms/bios/highscore.rom", "rb" );
|
||||
if (file == NULL) file = fopen("/data/bios/highscore.rom", "rb" );
|
||||
|
||||
if(file != NULL)
|
||||
{
|
||||
fread(high_score_buffer, 1, HSC_CART_ROM_SIZE, file );
|
||||
cartridge_LoadHighScoreSram();
|
||||
for( uint i = 0; i < HSC_CART_ROM_SIZE; i++ )
|
||||
{
|
||||
memory_Write( 0x3000 + i, high_score_buffer[i] );
|
||||
}
|
||||
high_score_cart_loaded = true;
|
||||
fread(high_score_rom, 1, HSC_CART_ROM_SIZE, file);
|
||||
for( uint i = 0; i < HSC_CART_ROM_SIZE; i++ )
|
||||
{
|
||||
memory_Write(0x3000 + i, high_score_rom[i]);
|
||||
}
|
||||
high_score_cart_loaded = true;
|
||||
|
||||
// Now read in the associated .hsc SRAM file (or set SRAM to defaults)
|
||||
cartridge_LoadHighScoreSram();
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
high_score_cart_loaded = false;
|
||||
high_score_cart_loaded = false;
|
||||
}
|
||||
|
||||
return high_score_cart_loaded;
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
|
|
@ -30,14 +30,13 @@
|
|||
#include "Equates.h"
|
||||
#include "Memory.h"
|
||||
#include "Hash.h"
|
||||
#include "Logger.h"
|
||||
#include "Pokey.h"
|
||||
#include "Archive.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
extern bool cartridge_LoadHighScoreCart(void);
|
||||
extern bool cartridge_SaveHighScoreSram(void);
|
||||
extern bool cartridge_SaveHighScoreSram(void);
|
||||
|
||||
extern byte high_score_cart_loaded;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,154 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Logger.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Logger.h"
|
||||
#define LOGGER_FILENAME "ProSystem.log"
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
byte logger_level = LOGGER_LEVEL_DEBUG;
|
||||
# if 0 //LUDO:
|
||||
static FILE* logger_file = NULL;
|
||||
# else
|
||||
# include <stdio.h>
|
||||
# define logger_file stdout
|
||||
# endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetTime
|
||||
// ----------------------------------------------------------------------------
|
||||
static char* logger_GetTime( ) {
|
||||
time_t current;
|
||||
time(¤t);
|
||||
char* timestring = ctime(¤t);
|
||||
return timestring.erase(timestring.find_first_of("\n"), 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Log
|
||||
// ----------------------------------------------------------------------------
|
||||
static void logger_Log(char* message, byte level, char* source) {
|
||||
#if 0
|
||||
if(logger_file != NULL) {
|
||||
char* entry = "[" + logger_GetTime( ) + "]";
|
||||
switch(level) {
|
||||
case LOGGER_LEVEL_ERROR:
|
||||
entry += "[ERROR]";
|
||||
break;
|
||||
case LOGGER_LEVEL_INFO:
|
||||
entry += "[INFO ]";
|
||||
break;
|
||||
default:
|
||||
entry += "[DEBUG]";
|
||||
break;
|
||||
}
|
||||
entry += " " + message;
|
||||
if(source.length( ) > 0) {
|
||||
entry += " {" + source + "}";
|
||||
}
|
||||
entry += "\n";
|
||||
fwrite(entry.c_str( ), 1, entry.length( ), logger_file);
|
||||
fflush(logger_file);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ----------------------------------------------------------------------------
|
||||
bool logger_Initialize( ) {
|
||||
logger_file = fopen(LOGGER_FILENAME, "w");
|
||||
return (logger_file != NULL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ----------------------------------------------------------------------------
|
||||
bool logger_Initialize(char* filename) {
|
||||
logger_file = fopen(filename.c_str( ), "w");
|
||||
return (logger_file != NULL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogError
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogError(char* message) {
|
||||
logger_LogError(message, "");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogError
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogError(char* message, char* source) {
|
||||
if(logger_level == LOGGER_LEVEL_ERROR || logger_level == LOGGER_LEVEL_INFO || logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
logger_Log(message, LOGGER_LEVEL_ERROR, source);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogInfo
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogInfo(char* message) {
|
||||
logger_LogInfo(message, "");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogInfo
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogInfo(char* message, char* source) {
|
||||
if(logger_level == LOGGER_LEVEL_INFO || logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
logger_Log(message, LOGGER_LEVEL_INFO, source);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogDebug
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogDebug(char* message) {
|
||||
logger_LogDebug(message, "");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogDebug
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogDebug(char* message, char* source) {
|
||||
if(logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
logger_Log(message, LOGGER_LEVEL_DEBUG, source);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Release
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_Release( ) {
|
||||
if(logger_file != NULL) {
|
||||
fclose(logger_file);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,65 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Logger.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
#define LOGGER_LEVEL_DEBUG 0
|
||||
#define LOGGER_LEVEL_INFO 1
|
||||
#define LOGGER_LEVEL_ERROR 2
|
||||
|
||||
#if 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
extern bool logger_Initialize( );
|
||||
extern bool logger_Initialize(char* filename);
|
||||
extern void logger_LogError(char* message);
|
||||
extern void logger_LogError(char* message, char* source);
|
||||
extern void logger_LogInfo(char* message);
|
||||
extern void logger_LogInfo(char* message, char* source);
|
||||
extern void logger_LogDebug(char* message);
|
||||
extern void logger_LogDebug(char* message, char* source);
|
||||
extern void logger_Release( );
|
||||
#else
|
||||
static inline bool logger_Initialize() {}
|
||||
static inline bool logger_Initialize(char* filename) {}
|
||||
static inline void logger_LogError(char* message) {}
|
||||
static inline void logger_LogError(char* message, char* source) {}
|
||||
static inline void logger_LogInfo(char* message) {}
|
||||
static inline void logger_LogInfo(char* message, char* source) {}
|
||||
static inline void logger_LogDebug(char* message) {}
|
||||
static inline void logger_LogDebug(char* message, char* source) {}
|
||||
static inline void logger_Release( ) {}
|
||||
#endif
|
||||
extern byte logger_level;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
1062
arm9/source/emu/Maria.c
Normal file
|
@ -24,30 +24,21 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#ifndef MARIA_H
|
||||
#define MARIA_H
|
||||
# if 0 //LUDO:
|
||||
#define MARIA_SURFACE_SIZE 93440
|
||||
# else
|
||||
#define MARIA_SURFACE_SIZE 77440
|
||||
# endif
|
||||
|
||||
// 93440 = 320 x 292
|
||||
// 77440 = 320 x 242
|
||||
#define MARIA_SURFACE_SIZE (128*1024) // DS screen buffer size
|
||||
|
||||
#include "Equates.h"
|
||||
#include "Pair.h"
|
||||
#include "Memory.h"
|
||||
#include "Rect.h"
|
||||
#include "Sally.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
||||
extern void maria_Reset( );
|
||||
extern ITCM_CODE uint maria_RenderScanline( );
|
||||
extern void maria_RenderScanline(void);
|
||||
extern void maria_RenderScanlineTOP(void);
|
||||
extern void maria_Clear( );
|
||||
extern rect maria_displayArea;
|
||||
extern rect maria_visibleArea;
|
||||
extern word* maria_surface;
|
||||
extern word maria_scanline;
|
||||
extern uint maria_scanline;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,557 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Maria.c
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Maria.h"
|
||||
|
||||
#include "ProSystem.h"
|
||||
|
||||
union ColorUnion
|
||||
{
|
||||
int32 color32;
|
||||
struct {
|
||||
byte color0;
|
||||
byte color1;
|
||||
byte color2;
|
||||
byte color3;
|
||||
} by;
|
||||
struct {
|
||||
word color0;
|
||||
word color1;
|
||||
} wo;
|
||||
};
|
||||
union ColorUnion colors __attribute__((section(".dtcm")));
|
||||
|
||||
#define MARIA_LINERAM_SIZE 160
|
||||
|
||||
rect maria_displayArea __attribute__((section(".dtcm"))) = {0, 16, 319, 258};
|
||||
rect maria_visibleArea __attribute__((section(".dtcm"))) = {0, 26, 319, 248};
|
||||
|
||||
word* maria_surface __attribute__((section(".dtcm"))) = 0;
|
||||
word maria_scanline __attribute__((section(".dtcm"))) = 1;
|
||||
|
||||
static byte maria_lineRAM[MARIA_LINERAM_SIZE+4] __attribute__((section(".dtcm")));
|
||||
static uint maria_cycles __attribute__((section(".dtcm")));
|
||||
static pair maria_dpp __attribute__((section(".dtcm")));
|
||||
static pair maria_dp __attribute__((section(".dtcm")));
|
||||
static pair maria_pp __attribute__((section(".dtcm")));
|
||||
static byte maria_horizontal __attribute__((section(".dtcm")));
|
||||
static byte maria_palette __attribute__((section(".dtcm")));
|
||||
static char maria_offset __attribute__((section(".dtcm")));
|
||||
static byte maria_h08 __attribute__((section(".dtcm")));
|
||||
static byte maria_h16 __attribute__((section(".dtcm")));
|
||||
static byte maria_wmode __attribute__((section(".dtcm")));
|
||||
|
||||
word *framePtr __attribute__((section(".dtcm"))) = (word *)0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//ClearCells - 4 bytes at a time
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void _maria_ClearCells4(void)
|
||||
{
|
||||
if (memory_ram[CTRL] & 4)
|
||||
{
|
||||
if ((maria_horizontal) < MARIA_LINERAM_SIZE)
|
||||
{
|
||||
*((u32 *)&maria_lineRAM[maria_horizontal]) = 0;
|
||||
}
|
||||
}
|
||||
maria_horizontal += 4;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreCells - 4 bytes at a time
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void _maria_StoreCells4(byte data)
|
||||
{
|
||||
if((maria_horizontal) < MARIA_LINERAM_SIZE)
|
||||
{
|
||||
byte *ptr = &(maria_lineRAM[maria_horizontal+3]);
|
||||
#ifdef KANGAROO_MODE_SUPPORTED
|
||||
if (memory_ram[CTRL] & 4)
|
||||
{
|
||||
if (data & 0x03) *ptr-- = maria_palette | (data & 0x03); else *ptr-- = 0;
|
||||
data = data >> 2;
|
||||
if (data & 0x03) *ptr-- = maria_palette | (data & 0x03); else *ptr-- = 0;
|
||||
data = data >> 2;
|
||||
if (data & 0x03) *ptr-- = maria_palette | (data & 0x03); else *ptr-- = 0;
|
||||
data = data >> 2;
|
||||
if (data) *ptr = maria_palette | (data); else *ptr = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (data & 0x03) *ptr-- = maria_palette | (data & 0x03); else ptr--;
|
||||
data = data >> 2;
|
||||
if (data & 0x03) *ptr-- = maria_palette | (data & 0x03); else ptr--;
|
||||
data = data >> 2;
|
||||
if (data & 0x03) *ptr-- = maria_palette | (data & 0x03); else ptr--;
|
||||
data = data >> 2;
|
||||
if (data) *ptr = maria_palette | (data);
|
||||
}
|
||||
}
|
||||
maria_horizontal += 4;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreCell - wide mode
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void maria_StoreCellWide(byte data)
|
||||
{
|
||||
if((maria_horizontal) < MARIA_LINERAM_SIZE)
|
||||
{
|
||||
byte *ptr = (byte *)&maria_lineRAM[maria_horizontal];
|
||||
if (data)
|
||||
{
|
||||
byte high=(data >> 4);
|
||||
byte low=(data & 0x0F);
|
||||
byte mp = (maria_palette & 16);
|
||||
if (high)
|
||||
{
|
||||
*ptr = mp | high;
|
||||
}
|
||||
if (low)
|
||||
{
|
||||
ptr++;
|
||||
*ptr = mp | low;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((memory_ram[CTRL] & 4))
|
||||
{
|
||||
*ptr++ = 0;
|
||||
*ptr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
maria_horizontal += 2;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsHolyDMA
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline bool maria_IsHolyDMA( )
|
||||
{
|
||||
if(maria_pp.w & 0x8000)
|
||||
{
|
||||
if(maria_h16 && (maria_pp.w & 4096)) {
|
||||
return true;
|
||||
}
|
||||
if(maria_h08 && (maria_pp.w & 2048)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetColor
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline byte maria_GetColor(byte data)
|
||||
{
|
||||
return (data & 3) ? memory_ram[BACKGRND + data] : memory_ram[BACKGRND];
|
||||
}
|
||||
|
||||
static u8 wide_lookup[256] __attribute__((section(".dtcm"))) =
|
||||
{
|
||||
0x00, 0x04, 0x08, 0x0C, 0x40, 0x44, 0x48, 0x4C, 0x80, 0x84, 0x88, 0x8C, 0xC0, 0xC4, 0xC8, 0xCC,
|
||||
0x01, 0x05, 0x09, 0x0D, 0x41, 0x45, 0x49, 0x4D, 0x81, 0x85, 0x89, 0x8D, 0xC1, 0xC5, 0xC9, 0xCD,
|
||||
0x02, 0x06, 0x0A, 0x0E, 0x42, 0x46, 0x4A, 0x4E, 0x82, 0x86, 0x8A, 0x8E, 0xC2, 0xC6, 0xCA, 0xCE,
|
||||
0x03, 0x07, 0x0B, 0x0F, 0x43, 0x47, 0x4B, 0x4F, 0x83, 0x87, 0x8B, 0x8F, 0xC3, 0xC7, 0xCB, 0xCF,
|
||||
0x10, 0x14, 0x18, 0x1C, 0x50, 0x54, 0x58, 0x5C, 0x90, 0x94, 0x98, 0x9C, 0xD0, 0xD4, 0xD8, 0xDC,
|
||||
0x11, 0x15, 0x19, 0x1D, 0x51, 0x55, 0x59, 0x5D, 0x91, 0x95, 0x99, 0x9D, 0xD1, 0xD5, 0xD9, 0xDD,
|
||||
0x12, 0x16, 0x1A, 0x1E, 0x52, 0x56, 0x5A, 0x5E, 0x92, 0x96, 0x9A, 0x9E, 0xD2, 0xD6, 0xDA, 0xDE,
|
||||
0x13, 0x17, 0x1B, 0x1F, 0x53, 0x57, 0x5B, 0x5F, 0x93, 0x97, 0x9B, 0x9F, 0xD3, 0xD7, 0xDB, 0xDF,
|
||||
0x20, 0x24, 0x28, 0x2C, 0x60, 0x64, 0x68, 0x6C, 0xA0, 0xA4, 0xA8, 0xAC, 0xE0, 0xE4, 0xE8, 0xEC,
|
||||
0x21, 0x25, 0x29, 0x2D, 0x61, 0x65, 0x69, 0x6D, 0xA1, 0xA5, 0xA9, 0xAD, 0xE1, 0xE5, 0xE9, 0xED,
|
||||
0x22, 0x26, 0x2A, 0x2E, 0x62, 0x66, 0x6A, 0x6E, 0xA2, 0xA6, 0xAA, 0xAE, 0xE2, 0xE6, 0xEA, 0xEE,
|
||||
0x23, 0x27, 0x2B, 0x2F, 0x63, 0x67, 0x6B, 0x6F, 0xA3, 0xA7, 0xAB, 0xAF, 0xE3, 0xE7, 0xEB, 0xEF,
|
||||
0x30, 0x34, 0x38, 0x3C, 0x70, 0x74, 0x78, 0x7C, 0xB0, 0xB4, 0xB8, 0xBC, 0xF0, 0xF4, 0xF8, 0xFC,
|
||||
0x31, 0x35, 0x39, 0x3D, 0x71, 0x75, 0x79, 0x7D, 0xB1, 0xB5, 0xB9, 0xBD, 0xF1, 0xF5, 0xF9, 0xFD,
|
||||
0x32, 0x36, 0x3A, 0x3E, 0x72, 0x76, 0x7A, 0x7E, 0xB2, 0xB6, 0xBA, 0xBE, 0xF2, 0xF6, 0xFA, 0xFE,
|
||||
0x33, 0x37, 0x3B, 0x3F, 0x73, 0x77, 0x7B, 0x7F, 0xB3, 0xB7, 0xBB, 0xBF, 0xF3, 0xF7, 0xFB, 0xFF
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreGraphic
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void maria_StoreGraphic( )
|
||||
{
|
||||
byte data = memory_ram[maria_pp.w];
|
||||
if(maria_wmode)
|
||||
{
|
||||
if(maria_IsHolyDMA())
|
||||
{
|
||||
maria_horizontal += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
maria_StoreCellWide(wide_lookup[data]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if KANGAROO_MODE_SUPPORTED
|
||||
if(maria_IsHolyDMA())
|
||||
{
|
||||
maria_horizontal += 4;
|
||||
}
|
||||
else if (!data)
|
||||
{
|
||||
_maria_ClearCells4();
|
||||
}
|
||||
#else
|
||||
if(maria_IsHolyDMA() || !data)
|
||||
{
|
||||
maria_horizontal += 4;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
_maria_StoreCells4(data);
|
||||
}
|
||||
}
|
||||
maria_pp.w++;
|
||||
}
|
||||
|
||||
static u8 wide_lookup_mode2A[] __attribute__((section(".dtcm"))) =
|
||||
{
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13,
|
||||
0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03,
|
||||
0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x11, 0x11, 0x13, 0x13
|
||||
};
|
||||
|
||||
|
||||
static u8 wide_lookup_mode2B[] __attribute__((section(".dtcm"))) =
|
||||
{
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13,
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13,
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13,
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13,
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13,
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13,
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13,
|
||||
0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03, 0x00, 0x02, 0x00, 0x02, 0x01, 0x03, 0x01, 0x03,
|
||||
0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13, 0x10, 0x12, 0x10, 0x12, 0x11, 0x13, 0x11, 0x13
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WriteLineRAM
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void maria_WriteLineRAM(word* buffer)
|
||||
{
|
||||
extern uint32 bg32;
|
||||
uint index;
|
||||
unsigned int *pix=(unsigned int *) buffer;
|
||||
uint32 *ptr = (uint32 *)&maria_lineRAM[0];
|
||||
byte rmode = memory_ram[CTRL] & 3;
|
||||
|
||||
if(rmode == 0)
|
||||
{
|
||||
for(index = 0; index < MARIA_LINERAM_SIZE/4; index++)
|
||||
{
|
||||
colors.color32 = *ptr++;
|
||||
if ((colors.wo.color0) == 0)
|
||||
{
|
||||
*pix++ = bg32;
|
||||
}
|
||||
else
|
||||
{
|
||||
word color, color1;
|
||||
color = maria_GetColor(colors.by.color0);
|
||||
color1 = maria_GetColor(colors.by.color1);
|
||||
*pix++ = color | (color<<8) | (color1<<16) | (color1<<24);
|
||||
}
|
||||
if ((colors.wo.color1) == 0)
|
||||
{
|
||||
*pix++ = bg32;
|
||||
}
|
||||
else
|
||||
{
|
||||
word color, color1;
|
||||
color = maria_GetColor(colors.by.color2);
|
||||
color1 = maria_GetColor(colors.by.color3);
|
||||
*pix++ = color | (color<<8) | (color1<<16) | (color1<<24);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(rmode == 2)
|
||||
{
|
||||
for(index = 0; index < MARIA_LINERAM_SIZE/4; index++)
|
||||
{
|
||||
colors.color32 = *ptr++;
|
||||
if (colors.color32 == 0)
|
||||
{
|
||||
*pix++ = bg32;
|
||||
*pix++ = bg32;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pix++ = maria_GetColor(wide_lookup_mode2A[colors.by.color0]) |
|
||||
maria_GetColor(wide_lookup_mode2B[colors.by.color0]) << 8 |
|
||||
maria_GetColor(wide_lookup_mode2A[colors.by.color1]) << 16 |
|
||||
maria_GetColor(wide_lookup_mode2B[colors.by.color1]) << 24;
|
||||
|
||||
*pix++ = maria_GetColor(wide_lookup_mode2A[colors.by.color2]) |
|
||||
maria_GetColor(wide_lookup_mode2B[colors.by.color2]) << 8 |
|
||||
maria_GetColor(wide_lookup_mode2A[colors.by.color3]) << 16 |
|
||||
maria_GetColor(wide_lookup_mode2B[colors.by.color3]) << 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(rmode == 3)
|
||||
{
|
||||
for(index = 0; index < MARIA_LINERAM_SIZE/4; index++)
|
||||
{
|
||||
colors.color32 = *ptr++;
|
||||
|
||||
if (colors.color32 == 0)
|
||||
{
|
||||
*pix++ = bg32;
|
||||
*pix++ = bg32;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pix++ = maria_GetColor((colors.by.color0 & 30)) |
|
||||
(maria_GetColor((colors.by.color0 & 28) | ((colors.by.color0 & 1) << 1)) <<8) |
|
||||
(maria_GetColor((colors.by.color1 & 30))<<16) |
|
||||
(maria_GetColor((colors.by.color1 & 28) | ((colors.by.color1 & 1) << 1)) <<24);
|
||||
*pix++ = maria_GetColor((colors.by.color2 & 30)) |
|
||||
(maria_GetColor((colors.by.color2 & 28) | ((colors.by.color2 & 1) << 1)) <<8) |
|
||||
(maria_GetColor((colors.by.color3 & 30))<<16) |
|
||||
(maria_GetColor((colors.by.color3 & 28) | ((colors.by.color3 & 1) << 1)) <<24);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreLineRAM
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void maria_StoreLineRAM( )
|
||||
{
|
||||
uint index;
|
||||
u32 *ptr=(u32*)maria_lineRAM;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;
|
||||
*ptr++ = 0;*ptr++ = 0;*ptr++ = 0;*ptr = 0;
|
||||
|
||||
byte mode = memory_ram[maria_dp.w + 1];
|
||||
while(mode & 0x5f)
|
||||
{
|
||||
byte width;
|
||||
byte indirect = 0;
|
||||
|
||||
maria_pp.b.l = memory_ram[maria_dp.w];
|
||||
maria_pp.b.h = memory_ram[maria_dp.w + 2];
|
||||
|
||||
if(mode & 31)
|
||||
{
|
||||
maria_cycles += 8; // Maria cycles (Header 4 byte)
|
||||
maria_palette = (memory_ram[maria_dp.w + 1] & 224) >> 3;
|
||||
maria_horizontal = memory_ram[maria_dp.w + 3];
|
||||
width = memory_ram[maria_dp.w + 1] & 31;
|
||||
width = ((~width) & 31) + 1;
|
||||
maria_dp.w += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
maria_cycles += 12; // Maria cycles (Header 5 byte)
|
||||
maria_palette = (memory_ram[maria_dp.w + 3] & 224) >> 3;
|
||||
maria_horizontal = memory_ram[maria_dp.w + 4];
|
||||
indirect = memory_ram[maria_dp.w + 1] & 32;
|
||||
maria_wmode = memory_ram[maria_dp.w + 1] & 128;
|
||||
width = memory_ram[maria_dp.w + 3] & 31;
|
||||
width = (width == 0)? 32: ((~width) & 31) + 1;
|
||||
maria_dp.w += 5;
|
||||
}
|
||||
|
||||
if(!indirect)
|
||||
{
|
||||
maria_pp.b.h += maria_offset;
|
||||
for(index = 0; index < width; index++)
|
||||
{
|
||||
maria_cycles += 3; // Maria cycles (Direct graphic read)
|
||||
maria_StoreGraphic();
|
||||
}
|
||||
}
|
||||
else {
|
||||
byte cwidth = memory_ram[CTRL] & 16;
|
||||
pair basePP = maria_pp;
|
||||
for(index = 0; index < width; index++) {
|
||||
//maria_cycles += 3; // Maria cycles (Indirect)
|
||||
maria_pp.b.l = memory_ram[basePP.w++];
|
||||
maria_pp.b.h = memory_ram[CHARBASE] + maria_offset;
|
||||
|
||||
maria_cycles += 6; // Maria cycles (Indirect, 1 byte)
|
||||
maria_StoreGraphic( );
|
||||
if(cwidth) {
|
||||
maria_cycles += 3; // Maria cycles (Indirect, 2 bytes)
|
||||
maria_StoreGraphic( );
|
||||
}
|
||||
}
|
||||
}
|
||||
mode = memory_ram[maria_dp.w + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void maria_Reset( ) {
|
||||
maria_surface = bufVideo;
|
||||
maria_scanline = 1;
|
||||
memset(maria_surface, 0, MARIA_SURFACE_SIZE);
|
||||
|
||||
// These values need to be reset to allow switching between carts.
|
||||
// This appears to be a bug in the ProSystem emulator.
|
||||
//
|
||||
maria_cycles = 0;
|
||||
maria_dpp.w = 0;
|
||||
maria_dp.w = 0;
|
||||
maria_pp.w = 0;
|
||||
maria_horizontal = 0;
|
||||
maria_palette = 0;
|
||||
maria_offset = 0;
|
||||
maria_h08 = 0;
|
||||
maria_h16 = 0;
|
||||
maria_wmode = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RenderScanline
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE uint maria_RenderScanline( )
|
||||
{
|
||||
extern u32 bg32;
|
||||
extern int gTotalAtariFrames;
|
||||
maria_cycles = 0;
|
||||
|
||||
//
|
||||
// Displays the background color when Maria is disabled (if applicable)
|
||||
//
|
||||
if( ( ( memory_ram[CTRL] & 96 ) != 64 ) && maria_scanline >= maria_visibleArea.top && maria_scanline <= maria_visibleArea.bottom)
|
||||
{
|
||||
u32 *bgstart = (u32*)framePtr;
|
||||
for(uint index = 0; index < MARIA_LINERAM_SIZE/4; index++ )
|
||||
{
|
||||
*bgstart++ = bg32;
|
||||
}
|
||||
}
|
||||
|
||||
if(((memory_ram[CTRL] & 0x60) == 0x40))
|
||||
{
|
||||
maria_cycles += 5; // Maria cycles (DMA Startup)
|
||||
if(maria_scanline == maria_displayArea.top)
|
||||
{
|
||||
maria_cycles += 10; // Maria cycles (End of VBLANK)
|
||||
maria_dpp.b.l = memory_ram[DPPL];
|
||||
maria_dpp.b.h = memory_ram[DPPH];
|
||||
maria_h08 = memory_ram[maria_dpp.w] & 32;
|
||||
maria_h16 = memory_ram[maria_dpp.w] & 64;
|
||||
maria_offset = memory_ram[maria_dpp.w] & 15;
|
||||
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
|
||||
maria_dp.b.h = memory_ram[maria_dpp.w + 1];
|
||||
if(memory_ram[maria_dpp.w] & 128)
|
||||
{
|
||||
maria_cycles += 20; // Maria cycles (NMI) /*29, 16, 20*/
|
||||
sally_ExecuteNMI( );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is where we render the video memory...
|
||||
if (gTotalAtariFrames & 1) // Skip every other frame...
|
||||
{
|
||||
maria_WriteLineRAM(framePtr);
|
||||
framePtr += 256;
|
||||
}
|
||||
}
|
||||
|
||||
if(maria_scanline != maria_displayArea.bottom)
|
||||
{
|
||||
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
|
||||
maria_dp.b.h = memory_ram[maria_dpp.w + 1];
|
||||
maria_StoreLineRAM( );
|
||||
maria_offset--;
|
||||
if(maria_offset < 0)
|
||||
{
|
||||
maria_cycles += 10; // Maria cycles (Last line of zone) ( /*20*/
|
||||
maria_dpp.w += 3;
|
||||
maria_h08 = memory_ram[maria_dpp.w] & 32;
|
||||
maria_h16 = memory_ram[maria_dpp.w] & 64;
|
||||
maria_offset = memory_ram[maria_dpp.w] & 15;
|
||||
if(memory_ram[maria_dpp.w] & 128)
|
||||
{
|
||||
maria_cycles += 20; // Maria cycles (NMI) /*29, 16, 20*/
|
||||
//ALEK Fst6502_Cause_Interrupt(IRQ_NMI);
|
||||
sally_ExecuteNMI( );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
maria_cycles += 4; // Maria cycles (Other lines of zone)
|
||||
}
|
||||
}
|
||||
}
|
||||
return maria_cycles;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Clear
|
||||
// ----------------------------------------------------------------------------
|
||||
void maria_Clear( )
|
||||
{
|
||||
maria_surface = bufVideo;
|
||||
memset(maria_surface, 0x00, MARIA_SURFACE_SIZE);
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
//
|
||||
// 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
|
||||
|
@ -22,241 +22,348 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Memory.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "ProSystem.h"
|
||||
#include "Memory.h"
|
||||
#include "Maria.h"
|
||||
#include "Database.h"
|
||||
|
||||
byte memory_ram[MEMORY_SIZE] = {0};
|
||||
byte memory_rom[MEMORY_SIZE] = {0};
|
||||
byte memory_ram[MEMORY_SIZE] ALIGN(32) = {0};
|
||||
u8 is_memory_writable[256] __attribute__((section(".dtcm")));
|
||||
u32 snes_bit_pos = 0;
|
||||
u8 bHSC_dirty = 0;
|
||||
u8 bINPTCTRL_locked = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_Reset( )
|
||||
void memory_Reset()
|
||||
{
|
||||
uint index;
|
||||
for(index = 0; index < MEMORY_SIZE; index++) {
|
||||
memory_ram[index] = 0;
|
||||
memory_rom[index] = 1;
|
||||
}
|
||||
for(index = 0; index < 16384; index++) {
|
||||
memory_rom[index] = 0;
|
||||
}
|
||||
uint index;
|
||||
for(index = 0x4000; index < MEMORY_SIZE; index++)
|
||||
{
|
||||
memory_ram[index] = 0xff;
|
||||
is_memory_writable[index >> 8] = 0;
|
||||
}
|
||||
for(index = 0; index < 0x4000; index++)
|
||||
{
|
||||
memory_ram[index] = 0x00;
|
||||
is_memory_writable[index >> 8] = 1;
|
||||
}
|
||||
|
||||
bHSC_dirty = 0;
|
||||
snes_bit_pos = 0;
|
||||
bINPTCTRL_locked = 0;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef DS_LITE
|
||||
ITCM_CODE byte memory_Read(word address)
|
||||
{
|
||||
if (cartridge_pokey)
|
||||
{
|
||||
if (cartridge_pokey == POKEY_AT_4000)
|
||||
{
|
||||
if ((address & 0xFFF0) == 0x4000) return pokey_GetRegister(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not quite accurate as it will catch anything from 0x440 to 0x4C0 but that's
|
||||
// good enough as nothing else should be mapped in this region except POKEY.
|
||||
if ((address & 0xFFC0) == 0x440) return pokey_GetRegister(0x4000 + (address - 0x0450));
|
||||
}
|
||||
}
|
||||
if ((address & 0xFFFC) == 0x284)
|
||||
{
|
||||
if (address & 0x1)
|
||||
{
|
||||
byte tmp_byte = memory_ram[INTFLG];
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return tmp_byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return memory_ram[INTIM];
|
||||
}
|
||||
}
|
||||
return memory_ram[address];
|
||||
ITCM_CODE byte memory_Read_Slower(word address)
|
||||
{
|
||||
extern u8 write_only_pokey_at_4000;
|
||||
|
||||
if((address & 0xFFFC) == 0x284)
|
||||
{
|
||||
if(address & 0x1)
|
||||
{
|
||||
byte tmp_byte = memory_ram[INTFLG];
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return tmp_byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return memory_ram[INTIM];
|
||||
}
|
||||
}
|
||||
else if(myCartInfo.pokeyType)
|
||||
{
|
||||
if(myCartInfo.pokeyType == POKEY_AT_4000)
|
||||
{
|
||||
if(((address & 0xFFF0) == 0x4000) && (!write_only_pokey_at_4000)) return pokey_GetRegister(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not quite accurate as it will catch anything from 0x440 to 0x4C0 but that's
|
||||
// good enough as nothing else should be mapped in this region except POKEY.
|
||||
if((address & 0xFFC0) == 0x440) return pokey_GetRegister(0x4000 | (address & 0xF));
|
||||
if((address & 0xFFF0) == 0x800) return pokey_GetRegister(0x4000 | (address & 0xF));
|
||||
}
|
||||
}
|
||||
return memory_ram[address];
|
||||
}
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Write
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void memory_Write(word address, byte data)
|
||||
ITCM_CODE void memory_Write(word address, byte data)
|
||||
{
|
||||
#ifndef DS_LITE
|
||||
if (cartridge_pokey)
|
||||
{
|
||||
if (cartridge_pokey == POKEY_AT_4000)
|
||||
{
|
||||
if ((address & 0xFFF0) == 0x4000)
|
||||
extern u32 bg32, maria_charbase;
|
||||
extern u8 bg8;
|
||||
|
||||
if(unlikely(myCartInfo.pokeyType))
|
||||
{
|
||||
if(myCartInfo.pokeyType == POKEY_AT_4000)
|
||||
{
|
||||
pokey_SetRegister(address, data);
|
||||
return;
|
||||
if((address & 0xFFF0) == 0x4000)
|
||||
{
|
||||
pokey_SetRegister(address, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not quite accurate as it will catch anything from 0x440 to 0x4C0 but that's
|
||||
// good enough as nothing else should be mapped in this region except POKEY.
|
||||
if ((address & 0xFFC0) == 0x440)
|
||||
{
|
||||
pokey_SetRegister(0x4000 + (address - 0x0450), data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!memory_rom[address])
|
||||
{
|
||||
switch(address) {
|
||||
case INPTCTRL:
|
||||
if(data == 22 && cartridge_IsLoaded( )) {
|
||||
cartridge_Store( );
|
||||
}
|
||||
else if(data == 2 && bios_enabled) {
|
||||
bios_Store( );
|
||||
}
|
||||
break;
|
||||
case INPT0:
|
||||
break;
|
||||
case INPT1:
|
||||
break;
|
||||
case INPT2:
|
||||
break;
|
||||
case INPT3:
|
||||
break;
|
||||
case INPT4:
|
||||
break;
|
||||
case INPT5:
|
||||
break;
|
||||
case AUDC0:
|
||||
tia_audc[0] = data & 15;
|
||||
tia_MemoryChannel(0);
|
||||
break;
|
||||
case AUDC1:
|
||||
tia_audc[1] = data & 15;
|
||||
tia_MemoryChannel(1);
|
||||
break;
|
||||
case AUDF0:
|
||||
tia_audf[0] = data & 31;
|
||||
tia_MemoryChannel(0);
|
||||
break;
|
||||
case AUDF1:
|
||||
tia_audf[1] = data & 31;
|
||||
tia_MemoryChannel(1);
|
||||
break;
|
||||
case AUDV0:
|
||||
tia_audv[0] = (data & 15) << 2;
|
||||
tia_MemoryChannel(0);
|
||||
break;
|
||||
case AUDV1:
|
||||
tia_audv[1] = (data & 15) << 2;
|
||||
tia_MemoryChannel(1);
|
||||
break;
|
||||
case WSYNC:
|
||||
if (cartridge_uses_wsync)
|
||||
else
|
||||
{
|
||||
memory_ram[WSYNC] = true;
|
||||
// Not quite accurate as it will catch anything from 0x440 to 0x4C0 but that's
|
||||
// good enough as nothing else should be mapped in this region except POKEY.
|
||||
if((address & 0xFFC0) == 0x440)
|
||||
{
|
||||
pokey_SetRegister(0x4000 | (address & 0x0F), data);
|
||||
return;
|
||||
}
|
||||
if((address & 0xFFF0) == 0x800) // Pokey @800
|
||||
{
|
||||
pokey_SetRegister(0x4000 | (address & 0x0F), data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SWCHB:
|
||||
/*gdement: Writing here actually writes to DRB inside the RIOT chip.
|
||||
This value only indirectly affects output of SWCHB.*/
|
||||
riot_SetDRB(data);
|
||||
break;
|
||||
case SWCHA:
|
||||
riot_SetDRA(data);
|
||||
break;
|
||||
case TIM1T:
|
||||
case TIM1T | 0x8:
|
||||
riot_SetTimer(TIM1T, data);
|
||||
break;
|
||||
case TIM8T:
|
||||
case TIM8T | 0x8:
|
||||
riot_SetTimer(TIM8T, data);
|
||||
break;
|
||||
case TIM64T:
|
||||
case TIM64T | 0x8:
|
||||
riot_SetTimer(TIM64T, data);
|
||||
break;
|
||||
case T1024T:
|
||||
case T1024T | 0x8:
|
||||
riot_SetTimer(T1024T, data);
|
||||
break;
|
||||
default:
|
||||
memory_ram[address] = data;
|
||||
if (address >= 8256)
|
||||
{
|
||||
// 0x2040 -> 0x20ff (0x2000)
|
||||
if(address >= 8256 && address <= 8447)
|
||||
{
|
||||
memory_ram[address - 8192] = data;
|
||||
}
|
||||
// 0x2140 -> 0x21ff (0x2000)
|
||||
else if(address >= 8512 && address <= 8703)
|
||||
{
|
||||
memory_ram[address - 8192] = data;
|
||||
}
|
||||
}
|
||||
else if (address <= 511)
|
||||
{
|
||||
// 0x40 -> 0xff (0x2000)
|
||||
if(address >= 64 && address <= 255)
|
||||
{
|
||||
memory_ram[address + 8192] = data;
|
||||
}
|
||||
// 0x140 -> 0x1ff (0x2000)
|
||||
else if(address >= 320 && address <= 511)
|
||||
{
|
||||
memory_ram[address + 8192] = data;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cartridge_Write(address, data);
|
||||
}
|
||||
|
||||
if(is_memory_writable[address >> 8])
|
||||
{
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// If this write would be in normal (non bankset) memory, we need to keep the bankset
|
||||
// memory up to date as well... This speeds up processing in Maria for banksets handling.
|
||||
// ---------------------------------------------------------------------------------------
|
||||
extern byte banksets_memory[];
|
||||
extern u16 banksets_mask;
|
||||
if(!(address & banksets_mask)) banksets_memory[address] = data;
|
||||
|
||||
if((address & 0x5000)) // This will catch RAM at 0x4000 and HSC at 0x1000
|
||||
{
|
||||
// For banking RAM we need to keep the shadow up to date.
|
||||
if((address & 0x5000) == 0x4000)
|
||||
{
|
||||
extern u8 * shadow_ram;
|
||||
shadow_ram[address] = data;
|
||||
|
||||
if(myCartInfo.cardtype == CARTRIDGE_TYPE_FRACTALUS)
|
||||
{
|
||||
// Special EXRAM/A8 handling... mirror ram
|
||||
memory_ram[address ^ 0x0100] = data;
|
||||
}
|
||||
memory_ram[address] = data;
|
||||
return;
|
||||
}
|
||||
else if((address & 0xF800) == 0x1000) // HSC RAM - set the dirty bit so we persist the .hsc file in the main loop
|
||||
{
|
||||
if(memory_ram[address] != data)
|
||||
{
|
||||
memory_ram[address] = data;
|
||||
if(address != 0x1007 && (address < 0x17FA)) // Don't count the 'function' address nor the temp score...
|
||||
{
|
||||
bHSC_dirty = 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if((address & 0xFFE0) == 0x460) return; // XM/Yamaha is mapped into 460 - 47F... do not respond to it as we are not XM capable (yet)
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Until we are 'locked' into a mode, address range 0x00 to 0x1f
|
||||
// (overlapping the TIA) will respond as write-only register INPTCTRL
|
||||
// ---------------------------------------------------------------------
|
||||
if((address & 0xFCFF) <= 0x1f)
|
||||
{
|
||||
if(!bINPTCTRL_locked)
|
||||
{
|
||||
if(data & 0x04) cartridge_Store();
|
||||
else bios_Store();
|
||||
}
|
||||
if(data & 0x01) bINPTCTRL_locked = 1;
|
||||
}
|
||||
|
||||
switch(address)
|
||||
{
|
||||
case INPT0:
|
||||
break;
|
||||
case INPT1:
|
||||
break;
|
||||
case INPT2:
|
||||
break;
|
||||
case INPT3:
|
||||
break;
|
||||
case INPT4:
|
||||
break;
|
||||
case INPT5:
|
||||
break;
|
||||
case BACKGRND:
|
||||
memory_ram[BACKGRND] = data;
|
||||
bg8 = data;
|
||||
bg32 = data | (data << 8) | (data << 16) | (data << 24);
|
||||
break;
|
||||
case CHARBASE:
|
||||
memory_ram[CHARBASE] = data;
|
||||
maria_charbase = data;
|
||||
break;
|
||||
case AUDC0:
|
||||
tia_audc[0] = data & 15;
|
||||
tia_MemoryChannel(0);
|
||||
break;
|
||||
case AUDC1:
|
||||
tia_audc[1] = data & 15;
|
||||
tia_MemoryChannel(1);
|
||||
break;
|
||||
case AUDF0:
|
||||
tia_audf[0] = data & 31;
|
||||
tia_MemoryChannel(0);
|
||||
break;
|
||||
case AUDF1:
|
||||
tia_audf[1] = data & 31;
|
||||
tia_MemoryChannel(1);
|
||||
break;
|
||||
case AUDV0:
|
||||
tia_audv[0] = (data & 15) << 2;
|
||||
tia_MemoryChannel(0);
|
||||
break;
|
||||
case AUDV1:
|
||||
tia_audv[1] = (data & 15) << 2;
|
||||
tia_MemoryChannel(1);
|
||||
break;
|
||||
case WSYNC:
|
||||
memory_ram[WSYNC] = true;
|
||||
riot_and_wsync |= 0x01;
|
||||
break;
|
||||
case SWCHB:
|
||||
/*gdement: Writing here actually writes to DRB inside the RIOT chip.
|
||||
This value only indirectly affects output of SWCHB.*/
|
||||
riot_SetDRB(data);
|
||||
break;
|
||||
case SWCHA:
|
||||
if(myCartInfo.cardctrl1 == SNES)
|
||||
{
|
||||
extern byte riot_dra;
|
||||
if((data & 0x20) != (riot_dra & 0x20)) // Change of Latch state
|
||||
{
|
||||
snes_bit_pos = 0;
|
||||
if(snes_adaptor & (1 << snes_bit_pos)) memory_ram[INPT4] |= 0x80;
|
||||
else memory_ram[INPT4] &= 0x7F;
|
||||
}
|
||||
if((data & 0x10) != (riot_dra & 0x10)) // Change of Clock state
|
||||
{
|
||||
if(data & 0x10) // Clock going High
|
||||
{
|
||||
snes_bit_pos++;
|
||||
}
|
||||
else // Clock going low
|
||||
{
|
||||
if(snes_bit_pos >= 17) snes_bit_pos = 0;
|
||||
if(snes_adaptor & (1 << snes_bit_pos)) memory_ram[INPT4] |= 0x80;
|
||||
else memory_ram[INPT4] &= 0x7F;
|
||||
}
|
||||
}
|
||||
}
|
||||
riot_SetDRA(data);
|
||||
break;
|
||||
case TIM1T:
|
||||
case TIM1T | 0x8:
|
||||
riot_SetTimer(TIM1T, data);
|
||||
break;
|
||||
case TIM8T:
|
||||
case TIM8T | 0x8:
|
||||
riot_SetTimer(TIM8T, data);
|
||||
break;
|
||||
case TIM64T:
|
||||
case TIM64T | 0x8:
|
||||
riot_SetTimer(TIM64T, data);
|
||||
break;
|
||||
case T1024T:
|
||||
case T1024T | 0x8:
|
||||
riot_SetTimer(T1024T, data);
|
||||
break;
|
||||
default:
|
||||
memory_ram[address] = data;
|
||||
#ifdef RAM_MIRRORS_ENABLED
|
||||
// ------------------------------------------------------
|
||||
// Handle the RAM mirrors that the 7800 presents...
|
||||
//
|
||||
// 0x2040 - 0x20FF RAM block 0 (mirror of 0x0040-00FF)
|
||||
// 0x2140 - 0x21FF RAM block 1 (mirror of 0x0140-01FF)
|
||||
// ------------------------------------------------------
|
||||
if(address >= 0x2040)
|
||||
{
|
||||
// 0x2040 -> 0x20ff (0x2000)
|
||||
if(address <= 0x20FF)
|
||||
{
|
||||
memory_ram[address & 0x00FF] = data;
|
||||
}
|
||||
// 0x2140 -> 0x21ff (0x2100)
|
||||
else if(address >= 0x2140 && address <= 0x21FF)
|
||||
{
|
||||
memory_ram[address & 0x01FF] = data;
|
||||
}
|
||||
}
|
||||
else if(address < 0x200)
|
||||
{
|
||||
// 0x40 -> 0xff (0x2000)
|
||||
if(address >= 0x40 && address <= 0xFF)
|
||||
{
|
||||
memory_ram[address | 0x2000] = data;
|
||||
}
|
||||
// 0x140 -> 0x1ff (0x2100)
|
||||
else if(address >= 0x140 && address <= 0x1FF)
|
||||
{
|
||||
memory_ram[address | 0x2000] = data;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cartridge_Write(address, data);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WriteROM
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void memory_WriteROM(word address, word size, const byte* data)
|
||||
ITCM_CODE void memory_WriteROM(word address, u32 size, const byte * data)
|
||||
{
|
||||
u32* ramPtr = (u32*)&memory_ram[address];
|
||||
u32* romPtr = (u32*)&memory_rom[address];
|
||||
u32* dataPtr = (u32*)data;
|
||||
for (word i=0; i<(size>>2); i++)
|
||||
{
|
||||
*ramPtr++ = *dataPtr++;
|
||||
*romPtr++ = 0x01010101;
|
||||
}
|
||||
memcpy( & memory_ram[address], data, size);
|
||||
memset( & is_memory_writable[address >> 8], 0x00, size >> 8);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WriteROMFast (assumes memory_rom[] already set properly)
|
||||
// WriteROMFast (assumes is_memory_writable[] already set properly)
|
||||
// size is already in multiples of 8x u32 dwords (32 bytes)
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void memory_WriteROMFast(word address, word size, const byte* data)
|
||||
ITCM_CODE void memory_WriteROMFast(word address, u32 size, const u32 * data)
|
||||
{
|
||||
u32* ramPtr = (u32*)&memory_ram[address];
|
||||
u32* dataPtr = (u32*)data;
|
||||
for (word i=0; i<(size>>2); i++)
|
||||
{
|
||||
*ramPtr++ = *dataPtr++;
|
||||
}
|
||||
u32 * ramPtr = (u32 * ) & memory_ram[address];
|
||||
u32 * dataPtr = (u32 * ) data;
|
||||
u32 size2 = size;
|
||||
do {
|
||||
* ramPtr++ = * dataPtr++;
|
||||
* ramPtr++ = * dataPtr++;
|
||||
* ramPtr++ = * dataPtr++;
|
||||
* ramPtr++ = * dataPtr++;
|
||||
* ramPtr++ = * dataPtr++;
|
||||
* ramPtr++ = * dataPtr++;
|
||||
* ramPtr++ = * dataPtr++;
|
||||
* ramPtr++ = * dataPtr++;
|
||||
}
|
||||
while(--size2);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ClearROM
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_ClearROM(word address, word size)
|
||||
void memory_ClearROM(word address, word size)
|
||||
{
|
||||
memset(&memory_ram[address], 0x00, size);
|
||||
memset(&memory_rom[address], 0x00, size);
|
||||
memset( & memory_ram[address], 0x00, size);
|
||||
memset( & is_memory_writable[address >> 8], 0xFF, size >> 8);
|
||||
}
|
||||
|
|
|
@ -27,27 +27,31 @@
|
|||
#define MEMORY_SIZE 65536
|
||||
|
||||
#include "Equates.h"
|
||||
#include "Bios.h"
|
||||
#include "Cartridge.h"
|
||||
#include "Tia.h"
|
||||
#include "Riot.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
extern void memory_Reset( );
|
||||
#ifndef DS_LITE
|
||||
extern ITCM_CODE byte memory_Read(word address);
|
||||
#endif
|
||||
extern ITCM_CODE void memory_Write(word address, byte data);
|
||||
//ALEK extern void memory_Write(byte data,word address);
|
||||
extern u8 bHSC_dirty;
|
||||
|
||||
extern void memory_WriteROM(word address, word size, const byte* data);
|
||||
extern void memory_WriteROMFast(word address, word size, const byte* data);
|
||||
extern void memory_WriteROM32(word address, word size, const byte* data);
|
||||
extern void memory_ClearROM(word address, word size);
|
||||
extern byte memory_ram[MEMORY_SIZE];
|
||||
extern byte memory_rom[MEMORY_SIZE];
|
||||
//ALEK extern byte *memory_rom;
|
||||
extern void memory_Reset( );
|
||||
|
||||
extern byte memory_Read_Slower(word address);
|
||||
extern void memory_Write(word address, byte data);
|
||||
extern void memory_WriteZP(word address, byte data);
|
||||
|
||||
inline byte memory_Read(word address)
|
||||
{
|
||||
if (address & 0x4E00) return memory_Read_Slower(address); // If these bits are set, might be POKEY access... or RIOT read
|
||||
else return memory_ram[address];
|
||||
}
|
||||
|
||||
extern void memory_WriteROM(word address, u32 size, const byte* data);
|
||||
extern void memory_WriteROMFast(word address, u32 size, const u32* data);
|
||||
extern void memory_ClearROM(word address, word size);
|
||||
|
||||
|
||||
extern byte* get_memory_ram();
|
||||
|
||||
|
|
|
@ -37,4 +37,17 @@ typedef union {
|
|||
} Pair;
|
||||
|
||||
typedef Pair pair;
|
||||
|
||||
typedef union {
|
||||
u32 w;
|
||||
struct {
|
||||
byte l;
|
||||
byte h;
|
||||
byte b2;
|
||||
byte b3;
|
||||
} b;
|
||||
} LPair;
|
||||
|
||||
typedef LPair lpair;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#define PALETTE_SOURCE "Palette.cpp"
|
||||
|
||||
char * palette_filename;
|
||||
bool palette_default = true;
|
||||
// 1.3
|
||||
|
||||
// Taken from Wii Port 0.5
|
||||
byte palette_data[PALETTE_SIZE] = {
|
||||
0x00,0x00,0x00,0x25,0x25,0x25,0x34,0x34,0x34,0x4F,0x4F,0x4F,
|
||||
0x5B,0x5B,0x5B,0x69,0x69,0x69,0x7B,0x7B,0x7B,0x8A,0x8A,0x8A,
|
||||
|
@ -69,12 +69,12 @@ byte palette_data[PALETTE_SIZE] = {
|
|||
0x00,0x71,0xC6,0x00,0x86,0xD0,0x0A,0x9B,0xDF,0x1A,0xA8,0xEC,
|
||||
0x2B,0xB6,0xFF,0x3F,0xC2,0xFF,0x45,0xCB,0xFF,0x59,0xD3,0xFF,
|
||||
0x7F,0xDA,0xFF,0x8F,0xDE,0xFF,0xA0,0xE2,0xFF,0xB0,0xEB,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x4C,0x00,0x00,0x6A,0x20,0x50,0x8E,0x79,
|
||||
0x40,0x99,0x99,0x00,0x9C,0xAA,0x00,0xA1,0xBB,0x01,0xA4,0xCC,
|
||||
0x03,0xA5,0xD7,0x05,0xDA,0xE2,0x18,0xE5,0xFF,0x34,0xEA,0xFF,
|
||||
0x00,0x38,0x39,0x00,0x3C,0x48,0x00,0x3D,0x5B,0x02,0x66,0x7F,
|
||||
0x03,0x73,0x83,0x00,0x9C,0xAA,0x00,0xA1,0xBB,0x01,0xA4,0xCC,
|
||||
0x03,0xBB,0xFF,0x05,0xDA,0xE2,0x18,0xE5,0xFF,0x34,0xEA,0xFF,
|
||||
0x49,0xEF,0xFF,0x66,0xF2,0xFF,0x84,0xF4,0xFF,0x9E,0xF9,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x5D,0x00,0x00,0x70,0x00,0x00,0x83,0x00,
|
||||
0x00,0x95,0x00,0x00,0xAB,0x00,0x07,0xBD,0x07,0x0A,0xD0,0x0A,
|
||||
0x00,0x4A,0x00,0x00,0x5D,0x00,0x00,0x70,0x00,0x00,0x8B,0x00,
|
||||
0x00,0xA9,0x00,0x00,0xBB,0x05,0x00,0xBD,0x00,0x02,0xD0,0x05,
|
||||
0x1A,0xD5,0x40,0x5A,0xF1,0x77,0x82,0xEF,0xA7,0x84,0xED,0xD1,
|
||||
0x89,0xFF,0xED,0x7D,0xFF,0xFF,0x93,0xFF,0xFF,0x9B,0xFF,0xFF,
|
||||
0x22,0x4A,0x03,0x27,0x53,0x04,0x30,0x64,0x05,0x3C,0x77,0x0C,
|
||||
|
@ -94,115 +94,21 @@ byte palette_data[PALETTE_SIZE] = {
|
|||
0xE6,0xA4,0x40,0xF4,0xB1,0x4B,0xFD,0xC1,0x58,0xFF,0xCC,0x55,
|
||||
0xFF,0xD4,0x61,0xFF,0xDD,0x69,0xFF,0xE6,0x79,0xFF,0xEA,0x98
|
||||
};
|
||||
#if 0
|
||||
// 1.2
|
||||
byte palette_data[PALETTE_SIZE] = {
|
||||
0x00,0x00,0x00,0x25,0x25,0x25,0x34,0x34,0x34,0x4F,0x4F,0x4F,
|
||||
0x5B,0x5B,0x5B,0x69,0x69,0x69,0x7B,0x7B,0x7B,0x8A,0x8A,0x8A,
|
||||
0xA7,0xA7,0xA7,0xB9,0xB9,0xB9,0xC5,0xC5,0xC5,0xD0,0xD0,0xD0,
|
||||
0xD7,0xD7,0xD7,0xE1,0xE1,0xE1,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,
|
||||
0x4C,0x32,0x00,0x62,0x3A,0x00,0x7B,0x4A,0x00,0x9A,0x60,0x00,
|
||||
0xB5,0x74,0x00,0xCC,0x85,0x00,0xE7,0x9E,0x08,0xF7,0xAF,0x10,
|
||||
0xFF,0xC3,0x18,0xFF,0xD0,0x20,0xFF,0xD8,0x28,0xFF,0xDF,0x30,
|
||||
0xFF,0xE6,0x3B,0xFF,0xF4,0x40,0xFF,0xFA,0x4B,0xFF,0xFF,0x50,
|
||||
0x99,0x25,0x00,0xAA,0x25,0x00,0xB4,0x25,0x00,0xD3,0x30,0x00,
|
||||
0xDD,0x48,0x02,0xE2,0x50,0x09,0xF4,0x67,0x00,0xF4,0x71,0x00,
|
||||
0xFF,0x9E,0x10,0xFF,0xAC,0x20,0xFF,0xBA,0x3A,0xFF,0xBF,0x50,
|
||||
0xFF,0xC6,0x6D,0xFF,0xD5,0x80,0xFF,0xE4,0x90,0xFF,0xE6,0x99,
|
||||
0x99,0x00,0x00,0xA9,0x00,0x00,0xC6,0x13,0x00,0xD8,0x04,0x00,
|
||||
0xE2,0x35,0x00,0xE4,0x40,0x00,0xE3,0x50,0x15,0xE3,0x52,0x25,
|
||||
0xFD,0x78,0x54,0xFF,0x8A,0x6A,0xFF,0x98,0x7C,0xFF,0xA4,0x8B,
|
||||
0xFF,0xB3,0x9E,0xFF,0xC2,0xB2,0xFF,0xD0,0xBA,0xFF,0xD7,0xC0,
|
||||
0x98,0x0C,0x0C,0xA7,0x0D,0x0D,0xAA,0x15,0x10,0xAA,0x15,0x15,
|
||||
0xD2,0x04,0x00,0xD3,0x08,0x00,0xD5,0x10,0x10,0xD6,0x10,0x30,
|
||||
0xFB,0x70,0x70,0xFB,0x7E,0x7E,0xFB,0x8F,0x8F,0xFF,0x9F,0x9F,
|
||||
0xFF,0xAB,0xAB,0xFF,0xB9,0xB9,0xFF,0xC9,0xC9,0xFF,0xCF,0xCF,
|
||||
0x7E,0x00,0x50,0x80,0x00,0x50,0x80,0x00,0x5F,0x95,0x0B,0x74,
|
||||
0xAA,0x22,0x88,0xBB,0x2F,0x9A,0xCE,0x3F,0xAD,0xD7,0x5A,0xB6,
|
||||
0xE4,0x67,0xC3,0xEF,0x72,0xCE,0xFB,0x7E,0xDA,0xFF,0x8D,0xE1,
|
||||
0xFF,0x9D,0xE5,0xFF,0xA5,0xE7,0xFF,0xAF,0xEA,0xFF,0xB8,0xEC,
|
||||
0x48,0x00,0x6C,0x5C,0x04,0x88,0x65,0x0D,0x90,0x7B,0x23,0xA7,
|
||||
0x93,0x3B,0xBF,0x9D,0x45,0xC9,0xA7,0x4F,0xD3,0xB2,0x5A,0xDE,
|
||||
0xBD,0x65,0xE9,0xC5,0x6D,0xF1,0xCE,0x76,0xFA,0xD5,0x83,0xFF,
|
||||
0xDA,0x90,0xFF,0xDE,0x9C,0xFF,0xE2,0xA9,0xFF,0xE6,0xB6,0xFF,
|
||||
0x1B,0x00,0x70,0x22,0x1B,0x8D,0x37,0x30,0xA2,0x48,0x41,0xB3,
|
||||
0x59,0x52,0xC4,0x63,0x5C,0xCE,0x6F,0x68,0xDA,0x7D,0x76,0xE8,
|
||||
0x87,0x80,0xF8,0x93,0x8C,0xFF,0x9D,0x97,0xFF,0xA8,0xA3,0xFF,
|
||||
0xB3,0xAF,0xFF,0xBC,0xB8,0xFF,0xC4,0xC1,0xFF,0xDA,0xD1,0xFF,
|
||||
0x00,0x0D,0x7F,0x00,0x12,0xA7,0x00,0x18,0xC0,0x0A,0x2B,0xD1,
|
||||
0x1B,0x4A,0xE3,0x2F,0x58,0xF0,0x37,0x68,0xFF,0x49,0x79,0xFF,
|
||||
0x5B,0x85,0xFF,0x6D,0x96,0xFF,0x7F,0xA3,0xFF,0x8C,0xAD,0xFF,
|
||||
0x96,0xB4,0xFF,0xA8,0xC0,0xFF,0xB7,0xCB,0xFF,0xC6,0xD6,0xFF,
|
||||
0x00,0x29,0x5A,0x00,0x38,0x76,0x00,0x48,0x92,0x00,0x5C,0xAC,
|
||||
0x00,0x71,0xC6,0x00,0x86,0xD0,0x0A,0x9B,0xDF,0x1A,0xA8,0xEC,
|
||||
0x2B,0xB6,0xFF,0x3F,0xC2,0xFF,0x45,0xCB,0xFF,0x59,0xD3,0xFF,
|
||||
0x7F,0xDA,0xFF,0x8F,0xDE,0xFF,0xA0,0xE2,0xFF,0xB0,0xEB,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x4C,0x00,0x00,0x6A,0x20,0x50,0x8E,0x79,
|
||||
0x40,0x99,0x99,0x00,0x9C,0xAA,0x00,0xA1,0xBB,0x01,0xA4,0xCC,
|
||||
0x03,0xA5,0xD7,0x05,0xDA,0xE2,0x18,0xE5,0xFF,0x34,0xEA,0xFF,
|
||||
0x49,0xEF,0xFF,0x66,0xF2,0xFF,0x84,0xF4,0xFF,0x9E,0xF9,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x5D,0x00,0x00,0x70,0x00,0x00,0x83,0x00,
|
||||
0x00,0x95,0x00,0x00,0xAB,0x00,0x07,0xBD,0x07,0x0A,0xD0,0x0A,
|
||||
0x1A,0xD5,0x40,0x5A,0xF1,0x77,0x82,0xEF,0xA7,0x84,0xED,0xD1,
|
||||
0x89,0xFF,0xED,0x7D,0xFF,0xFF,0x93,0xFF,0xFF,0x9B,0xFF,0xFF,
|
||||
0x22,0x4A,0x03,0x27,0x53,0x04,0x30,0x64,0x05,0x3C,0x77,0x0C,
|
||||
0x45,0x8C,0x11,0x5A,0xA5,0x13,0x1B,0xD2,0x09,0x1F,0xDD,0x00,
|
||||
0x3D,0xCD,0x2D,0x3D,0xCD,0x30,0x58,0xCC,0x40,0x60,0xD3,0x50,
|
||||
0xA2,0xEC,0x55,0xB3,0xF2,0x4A,0xBB,0xF6,0x5D,0xC4,0xF8,0x70,
|
||||
0x2E,0x3F,0x0C,0x36,0x4A,0x0F,0x40,0x56,0x15,0x46,0x5F,0x17,
|
||||
0x57,0x77,0x1A,0x65,0x85,0x1C,0x74,0x93,0x1D,0x8F,0xA5,0x25,
|
||||
0xAD,0xB7,0x2C,0xBC,0xC7,0x30,0xC9,0xD5,0x33,0xD4,0xE0,0x3B,
|
||||
0xE0,0xEC,0x42,0xEA,0xF6,0x45,0xF0,0xFD,0x47,0xF4,0xFF,0x6F,
|
||||
0x5A,0x24,0x00,0x55,0x24,0x00,0x64,0x2D,0x06,0x92,0x55,0x2B,
|
||||
0x9F,0x66,0x20,0xBB,0x85,0x00,0xC1,0xA1,0x20,0xD0,0xB0,0x2F,
|
||||
0xDE,0xBE,0x3F,0xE6,0xC6,0x45,0xED,0xCD,0x57,0xF5,0xDB,0x62,
|
||||
0xFB,0xE5,0x69,0xFC,0xEE,0x6F,0xFD,0xF3,0x77,0xFD,0xF3,0x7F,
|
||||
0x5C,0x27,0x00,0x5C,0x27,0x00,0x75,0x2D,0x06,0x92,0x48,0x08,
|
||||
0x92,0x50,0x18,0xBB,0x72,0x20,0xC5,0x86,0x29,0xD7,0x96,0x33,
|
||||
0xE6,0xA4,0x40,0xF4,0xB1,0x4B,0xFD,0xC1,0x58,0xFF,0xCC,0x55,
|
||||
0xFF,0xD4,0x61,0xFF,0xDD,0x69,0xFF,0xE6,0x79,0xFF,0xEA,0x98
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
#if 0
|
||||
bool palette_Load(char * filename) {
|
||||
#if 0
|
||||
if(strlen(filename ) == 0) {
|
||||
logger_LogError("Palette filename is invalid.", PALETTE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger_LogInfo("Opening palette file " + filename + ".");
|
||||
#endif
|
||||
|
||||
FILE* file = fopen(filename.c_str( ), "rb");
|
||||
if(file == NULL) {
|
||||
logger_LogError("Failed to open the palette file " + filename + " for reading.", PALETTE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fread(palette_data, 1, PALETTE_SIZE, file) != PALETTE_SIZE) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to read the palette data.", PALETTE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
palette_filename = filename;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
void palette_Load(const byte* data) {
|
||||
uint index;
|
||||
u16 index;
|
||||
for(index = 0; index < PALETTE_SIZE; index++) {
|
||||
palette_data[index] = data[index];
|
||||
}
|
||||
|
||||
for(index = 0; index < 256; index++) {
|
||||
word r = palette_data[(index * 3) + 0];
|
||||
word g = palette_data[(index * 3) + 1];
|
||||
word b = palette_data[(index * 3) + 2];
|
||||
BG_PALETTE[index] = RGB8(r, g, b);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,15 +27,11 @@
|
|||
#define PALETTE_SIZE 768
|
||||
|
||||
#include <string.h>
|
||||
#include "Logger.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
||||
//extern bool palette_Load(char *filename);
|
||||
extern void palette_Load(const byte* data);
|
||||
extern char *palette_filename;
|
||||
extern byte palette_data[PALETTE_SIZE];
|
||||
extern bool palette_default;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include <stdlib.h>
|
||||
#include "Pokey.h"
|
||||
#include "ProSystem.h"
|
||||
#include "Sound.h"
|
||||
|
||||
#define POKEY_NOTPOLY5 0x80
|
||||
#define POKEY_POLY4 0x40
|
||||
#define POKEY_PURE 0x20
|
||||
|
@ -69,29 +69,29 @@
|
|||
|
||||
#define SK_RESET 0x03
|
||||
|
||||
byte pokey_buffer[SNDLENGTH] = {0};
|
||||
uint pokey_size = SNDLENGTH;
|
||||
extern byte TIA_POLY4[];
|
||||
extern byte TIA_POLY5[];
|
||||
|
||||
int pokeyBufIdx = 0;
|
||||
u32 pokeyBufIdx __attribute__((section(".dtcm"))) = 0;
|
||||
|
||||
static uint pokey_frequency = 1787520;
|
||||
static uint pokey_sampleRate = (31440/2);
|
||||
static byte pokey_audf[4];
|
||||
static byte pokey_audc[4];
|
||||
static byte pokey_audctl;
|
||||
static uint pokey_audf[4];
|
||||
static uint pokey_audc[4];
|
||||
static uint pokey_audctl __attribute__((section(".dtcm")));
|
||||
static byte pokey_output[4];
|
||||
static byte pokey_outVol[4];
|
||||
static byte pokey_poly04[POKEY_POLY4_SIZE] = {1,1,0,1,1,1,0,0,0,0,1,0,1,0,0};
|
||||
static byte pokey_poly05[POKEY_POLY5_SIZE] = {0,0,1,1,0,0,0,1,1,1,1,0,0,1,0,1,0,1,1,0,1,1,1,0,1,0,0,0,0,0,1};
|
||||
#define pokey_poly04 TIA_POLY4
|
||||
#define pokey_poly05 TIA_POLY5
|
||||
static byte pokey_poly17[POKEY_POLY17_SIZE];
|
||||
static uint pokey_poly17Size;
|
||||
static uint pokey_polyAdjust;
|
||||
static uint pokey_poly04Cntr;
|
||||
static uint pokey_poly05Cntr;
|
||||
static uint pokey_poly17Cntr;
|
||||
static uint pokey_polyAdjust __attribute__((section(".dtcm")));
|
||||
static uint pokey_poly04Cntr __attribute__((section(".dtcm")));
|
||||
static uint pokey_poly05Cntr __attribute__((section(".dtcm")));
|
||||
static uint pokey_poly17Cntr __attribute__((section(".dtcm")));
|
||||
static uint pokey_divideMax[4];
|
||||
static uint pokey_divideCount[4];
|
||||
static uint pokey_sampleMax;
|
||||
static uint pokey_sampleMax __attribute__((section(".dtcm")));
|
||||
static uint pokey_sampleCount[2];
|
||||
static uint pokey_baseMultiplier;
|
||||
|
||||
|
@ -100,13 +100,12 @@ static byte rand17[0x1ffff];
|
|||
static uint r9;
|
||||
static uint r17;
|
||||
static byte SKCTL;
|
||||
byte RANDOM;
|
||||
|
||||
byte POT_input[8] = {228, 228, 228, 228, 228, 228, 228, 228};
|
||||
static int pot_scanline;
|
||||
|
||||
static uint32 random_scanline_counter;
|
||||
static uint32 prev_random_scanline_counter;
|
||||
uint32 random_scanline_counter __attribute__((section(".dtcm")));
|
||||
uint32 prev_random_scanline_counter __attribute__((section(".dtcm")));
|
||||
|
||||
static void rand_init(byte *rng, int size, int left, int right, int add)
|
||||
{
|
||||
|
@ -167,7 +166,6 @@ void pokey_Reset( )
|
|||
rand_init(rand17, 17,16, 1, 0x1c000);
|
||||
|
||||
SKCTL = SK_RESET;
|
||||
RANDOM = 0;
|
||||
|
||||
r9 = 0;
|
||||
r17 = 0;
|
||||
|
@ -178,41 +176,13 @@ void pokey_Reset( )
|
|||
}
|
||||
|
||||
|
||||
/* Called prior to each scanline */
|
||||
void pokey_Scanline()
|
||||
{
|
||||
random_scanline_counter += CYCLES_PER_SCANLINE;
|
||||
|
||||
if (pot_scanline < 228)
|
||||
pot_scanline++;
|
||||
}
|
||||
|
||||
byte pokey_GetRegister(word address)
|
||||
{
|
||||
byte data = 0;
|
||||
|
||||
byte addr = address & 0x0f;
|
||||
if (addr < 8)
|
||||
if (address == POKEY_RANDOM)
|
||||
{
|
||||
byte b = POT_input[addr];
|
||||
if (b <= pot_scanline)
|
||||
return b;
|
||||
return pot_scanline;
|
||||
}
|
||||
|
||||
switch (address) {
|
||||
case POKEY_ALLPOT: {
|
||||
byte b = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (POT_input[addr] <= pot_scanline)
|
||||
b &= ~(1 << i); /* reset bit if pot value known */
|
||||
return b;
|
||||
}
|
||||
case POKEY_RANDOM:
|
||||
{
|
||||
uint32 prosystem_extra_cycles = 0; ///tbd
|
||||
uint32 curr_scanline_counter =
|
||||
( random_scanline_counter + prosystem_cycles + prosystem_extra_cycles );
|
||||
uint32 curr_scanline_counter = ( random_scanline_counter + prosystem_cycles );
|
||||
|
||||
if( SKCTL & SK_RESET )
|
||||
{
|
||||
|
@ -225,6 +195,7 @@ byte pokey_GetRegister(word address)
|
|||
r9 = 0;
|
||||
r17 = 0;
|
||||
}
|
||||
byte RANDOM;
|
||||
if( pokey_audctl & POKEY_POLY9 )
|
||||
{
|
||||
RANDOM = rand9[r9];
|
||||
|
@ -238,8 +209,6 @@ byte pokey_GetRegister(word address)
|
|||
|
||||
RANDOM = RANDOM ^ 0xff;
|
||||
data = RANDOM;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -250,8 +219,8 @@ byte pokey_GetRegister(word address)
|
|||
// ----------------------------------------------------------------------------
|
||||
// SetRegister
|
||||
// ----------------------------------------------------------------------------
|
||||
void pokey_SetRegister(word address, byte value) {
|
||||
byte channelMask;
|
||||
ITCM_CODE void pokey_SetRegister(word address, byte value) {
|
||||
uint channelMask;
|
||||
uint channel;
|
||||
|
||||
switch(address) {
|
||||
|
@ -428,88 +397,174 @@ static inline uint loc_get_int(byte *p)
|
|||
|
||||
static inline void loc_set_byte(byte *p, uint v)
|
||||
{
|
||||
u32 *ptr32 = (u32 *)p;
|
||||
*ptr32 = v;
|
||||
*((u32 *)p) = v;
|
||||
}
|
||||
|
||||
extern u32 tiaBufIdx;
|
||||
// ----------------------------------------------------------------------------
|
||||
// Process
|
||||
// ----------------------------------------------------------------------------
|
||||
void pokey_Process(uint length)
|
||||
ITCM_CODE void pokey_Process(void)
|
||||
{
|
||||
byte* buffer = pokey_buffer + pokeyBufIdx;
|
||||
byte* sampleCntrPtrB = ((byte*)&pokey_sampleCount[0]) + 1;
|
||||
if (tia_wait) return;
|
||||
|
||||
while(length)
|
||||
{
|
||||
int currentValue;
|
||||
byte nextEvent = POKEY_SAMPLE;
|
||||
uint eventMin = loc_get_int(sampleCntrPtrB);
|
||||
|
||||
byte channel;
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
if(pokey_divideCount[channel] <= eventMin) {
|
||||
eventMin = pokey_divideCount[channel];
|
||||
nextEvent = channel;
|
||||
}
|
||||
}
|
||||
byte* sampleCntrPtrB = ((byte*)&pokey_sampleCount[0]) + 1;
|
||||
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
pokey_divideCount[channel] -= eventMin;
|
||||
}
|
||||
|
||||
uint new_value = loc_get_int(sampleCntrPtrB) - eventMin;
|
||||
loc_set_byte(sampleCntrPtrB, new_value);
|
||||
|
||||
pokey_polyAdjust += eventMin;
|
||||
|
||||
if(nextEvent != POKEY_SAMPLE)
|
||||
while (1)
|
||||
{
|
||||
pokey_poly04Cntr = (pokey_poly04Cntr + pokey_polyAdjust) % POKEY_POLY4_SIZE;
|
||||
pokey_poly05Cntr = (pokey_poly05Cntr + pokey_polyAdjust) % POKEY_POLY5_SIZE;
|
||||
pokey_poly17Cntr = (pokey_poly17Cntr + pokey_polyAdjust) % pokey_poly17Size;
|
||||
pokey_polyAdjust = 0;
|
||||
pokey_divideCount[nextEvent] += pokey_divideMax[nextEvent];
|
||||
int currentValue;
|
||||
uint nextEvent = POKEY_SAMPLE;
|
||||
uint eventMin = loc_get_int(sampleCntrPtrB);
|
||||
|
||||
if((pokey_audc[nextEvent] & POKEY_NOTPOLY5) || pokey_poly05[pokey_poly05Cntr]) {
|
||||
if(pokey_audc[nextEvent] & POKEY_PURE) {
|
||||
pokey_output[nextEvent] = !pokey_output[nextEvent];
|
||||
byte channel;
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
if(pokey_divideCount[channel] <= eventMin) {
|
||||
eventMin = pokey_divideCount[channel];
|
||||
nextEvent = channel;
|
||||
}
|
||||
}
|
||||
else if (pokey_audc[nextEvent] & POKEY_POLY4) {
|
||||
pokey_output[nextEvent] = pokey_poly04[pokey_poly04Cntr];
|
||||
}
|
||||
else {
|
||||
pokey_output[nextEvent] = pokey_poly17[pokey_poly17Cntr];
|
||||
}
|
||||
}
|
||||
|
||||
if(pokey_output[nextEvent]) {
|
||||
pokey_outVol[nextEvent] = pokey_audc[nextEvent] & POKEY_VOLUME_MASK;
|
||||
}
|
||||
else {
|
||||
pokey_outVol[nextEvent] = 0;
|
||||
}
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
pokey_divideCount[channel] -= eventMin;
|
||||
}
|
||||
|
||||
uint new_value = loc_get_int(sampleCntrPtrB) - eventMin;
|
||||
loc_set_byte(sampleCntrPtrB, new_value);
|
||||
|
||||
pokey_polyAdjust += eventMin;
|
||||
|
||||
if(nextEvent != POKEY_SAMPLE)
|
||||
{
|
||||
pokey_poly04Cntr = (pokey_poly04Cntr + pokey_polyAdjust) % POKEY_POLY4_SIZE;
|
||||
pokey_poly05Cntr = (pokey_poly05Cntr + pokey_polyAdjust) % POKEY_POLY5_SIZE;
|
||||
pokey_poly17Cntr = (pokey_poly17Cntr + pokey_polyAdjust) % pokey_poly17Size;
|
||||
pokey_polyAdjust = 0;
|
||||
pokey_divideCount[nextEvent] += pokey_divideMax[nextEvent];
|
||||
|
||||
if((pokey_audc[nextEvent] & POKEY_NOTPOLY5) || pokey_poly05[pokey_poly05Cntr]) {
|
||||
if(pokey_audc[nextEvent] & POKEY_PURE) {
|
||||
pokey_output[nextEvent] = !pokey_output[nextEvent];
|
||||
}
|
||||
else if (pokey_audc[nextEvent] & POKEY_POLY4) {
|
||||
pokey_output[nextEvent] = pokey_poly04[pokey_poly04Cntr];
|
||||
}
|
||||
else {
|
||||
pokey_output[nextEvent] = pokey_poly17[pokey_poly17Cntr];
|
||||
}
|
||||
}
|
||||
|
||||
if(pokey_output[nextEvent]) {
|
||||
pokey_outVol[nextEvent] = pokey_audc[nextEvent] & POKEY_VOLUME_MASK;
|
||||
}
|
||||
else {
|
||||
pokey_outVol[nextEvent] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pokey_sampleCount += pokey_sampleMax;
|
||||
currentValue = 0;
|
||||
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++)
|
||||
{
|
||||
currentValue += pokey_outVol[channel];
|
||||
}
|
||||
|
||||
extern int TIA_Sample(void);
|
||||
currentValue = (currentValue << 2) + 8;
|
||||
currentValue += TIA_Sample();
|
||||
//currentValue = (currentValue >> 1);
|
||||
if (currentValue > 127) {currentValue = 127;} // Clip
|
||||
|
||||
// We have filled the buffer... let the buffer drain a bit
|
||||
if (((tiaBufIdx+1) & (SNDLENGTH-1)) == myTiaBufIdx)
|
||||
{
|
||||
tia_wait = (SNDLENGTH >> 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_buffer[tiaBufIdx++] = (u16)((currentValue<<8) | currentValue);
|
||||
tiaBufIdx &= (SNDLENGTH-1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
|
||||
u16 pokey_ProcessNow(void)
|
||||
{
|
||||
byte* sampleCntrPtrB = ((byte*)&pokey_sampleCount[0]) + 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
*pokey_sampleCount += pokey_sampleMax;
|
||||
currentValue = 0;
|
||||
int currentValue;
|
||||
uint nextEvent = POKEY_SAMPLE;
|
||||
uint eventMin = loc_get_int(sampleCntrPtrB);
|
||||
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++)
|
||||
{
|
||||
currentValue += pokey_outVol[channel];
|
||||
}
|
||||
byte channel;
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
if(pokey_divideCount[channel] <= eventMin) {
|
||||
eventMin = pokey_divideCount[channel];
|
||||
nextEvent = channel;
|
||||
}
|
||||
}
|
||||
|
||||
extern int TIA_Sample(void);
|
||||
currentValue = (currentValue << 2) + 8;
|
||||
currentValue += TIA_Sample();
|
||||
currentValue = (currentValue >> 1);
|
||||
*buffer++ = currentValue;
|
||||
pokeyBufIdx++;
|
||||
pokeyBufIdx &= (SNDLENGTH-1);
|
||||
length--;
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
pokey_divideCount[channel] -= eventMin;
|
||||
}
|
||||
|
||||
uint new_value = loc_get_int(sampleCntrPtrB) - eventMin;
|
||||
loc_set_byte(sampleCntrPtrB, new_value);
|
||||
|
||||
pokey_polyAdjust += eventMin;
|
||||
|
||||
if(nextEvent != POKEY_SAMPLE)
|
||||
{
|
||||
pokey_poly04Cntr = (pokey_poly04Cntr + pokey_polyAdjust) % POKEY_POLY4_SIZE;
|
||||
pokey_poly05Cntr = (pokey_poly05Cntr + pokey_polyAdjust) % POKEY_POLY5_SIZE;
|
||||
pokey_poly17Cntr = (pokey_poly17Cntr + pokey_polyAdjust) % pokey_poly17Size;
|
||||
pokey_polyAdjust = 0;
|
||||
pokey_divideCount[nextEvent] += pokey_divideMax[nextEvent];
|
||||
|
||||
if((pokey_audc[nextEvent] & POKEY_NOTPOLY5) || pokey_poly05[pokey_poly05Cntr]) {
|
||||
if(pokey_audc[nextEvent] & POKEY_PURE) {
|
||||
pokey_output[nextEvent] = !pokey_output[nextEvent];
|
||||
}
|
||||
else if (pokey_audc[nextEvent] & POKEY_POLY4) {
|
||||
pokey_output[nextEvent] = pokey_poly04[pokey_poly04Cntr];
|
||||
}
|
||||
else {
|
||||
pokey_output[nextEvent] = pokey_poly17[pokey_poly17Cntr];
|
||||
}
|
||||
}
|
||||
|
||||
if(pokey_output[nextEvent]) {
|
||||
pokey_outVol[nextEvent] = pokey_audc[nextEvent] & POKEY_VOLUME_MASK;
|
||||
}
|
||||
else {
|
||||
pokey_outVol[nextEvent] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pokey_sampleCount += pokey_sampleMax;
|
||||
currentValue = 0;
|
||||
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++)
|
||||
{
|
||||
currentValue += pokey_outVol[channel];
|
||||
}
|
||||
|
||||
extern int TIA_Sample(void);
|
||||
currentValue = (currentValue << 2) + 8;
|
||||
currentValue += TIA_Sample();
|
||||
//currentValue = (currentValue >> 1);
|
||||
if (currentValue > 127) {currentValue = 127;} // Clip
|
||||
|
||||
return (u16)((currentValue << 8) | currentValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -518,7 +573,7 @@ void pokey_Process(uint length)
|
|||
void pokey_Clear( ) {
|
||||
uint index;
|
||||
for(index = 0; index < SNDLENGTH; index++) {
|
||||
pokey_buffer[index] = 0;
|
||||
tia_buffer[index] = 0;
|
||||
pokeyBufIdx=0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,17 +71,22 @@
|
|||
#define POKEY_IRQST 0x400e
|
||||
#define POKEY_SKSTAT 0x400f
|
||||
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
#define CYCLES_PER_SCANLINE 454
|
||||
|
||||
extern void pokey_Reset( );
|
||||
extern void pokey_SetRegister(word address, byte value);
|
||||
extern byte pokey_GetRegister(word address);
|
||||
extern void pokey_Process(uint length);
|
||||
extern void pokey_Scanline();
|
||||
extern void pokey_Process(void);
|
||||
extern u16 pokey_ProcessNow(void);
|
||||
extern void pokey_Clear( );
|
||||
extern byte pokey_buffer[];
|
||||
extern uint pokey_size;
|
||||
extern uint32 random_scanline_counter;
|
||||
|
||||
/* Called prior to each scanline */
|
||||
inline void pokey_Scanline()
|
||||
{
|
||||
random_scanline_counter += CYCLES_PER_SCANLINE;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,141 +23,168 @@
|
|||
// ProSystem.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <malloc.h>
|
||||
#include "ProSystem.h"
|
||||
#include "Sound.h"
|
||||
#define PRO_SYSTEM_SOURCE "ProSystem.cpp"
|
||||
#define PRO_SYSTEM_STATE_HEADER "PRO-SYSTEM STATE"
|
||||
#include "Database.h"
|
||||
|
||||
#define CYCLES_PER_SCANLINE 454
|
||||
extern u8 isDS_LITE;
|
||||
extern u8 frameSkipMask;
|
||||
|
||||
bool prosystem_active __attribute__((section(".dtcm"))) = false;
|
||||
bool prosystem_paused __attribute__((section(".dtcm"))) = false;
|
||||
word prosystem_frequency __attribute__((section(".dtcm"))) = 60;
|
||||
word prosystem_scanlines __attribute__((section(".dtcm"))) = 262;
|
||||
uint prosystem_cycles __attribute__((section(".dtcm"))) = 0;
|
||||
uint32 bg32 __attribute__((section(".dtcm"))) = 0;
|
||||
uint32 bg32 __attribute__((section(".dtcm"))) = 0;
|
||||
uint bRenderFrame __attribute__((section(".dtcm"))) = 0;
|
||||
|
||||
|
||||
#define CYCLES_BEFORE_DMA 28 // Number of cycles before DMA kicks in (really 7 CPU cycles)
|
||||
#define CYCLES_PER_SCANLINE 454 // 454 Cycles per Scanline in an NTSC system (really 113.5 CPU cycles)
|
||||
|
||||
// Whether the last CPU operation resulted in a half cycle (need to take it
|
||||
// into consideration)
|
||||
extern bool half_cycle;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Reset( )
|
||||
void prosystem_Reset()
|
||||
{
|
||||
if(cartridge_IsLoaded( ))
|
||||
{
|
||||
prosystem_paused = false;
|
||||
sally_Reset( );
|
||||
region_Reset( );
|
||||
tia_Clear( );
|
||||
tia_Reset( );
|
||||
pokey_Clear( );
|
||||
pokey_Reset( );
|
||||
memory_Reset( );
|
||||
maria_Clear( );
|
||||
maria_Reset( );
|
||||
riot_Reset ( );
|
||||
cartridge_LoadHighScoreCart();
|
||||
if(bios_enabled)
|
||||
if(cartridge_IsLoaded())
|
||||
{
|
||||
bios_Store( );
|
||||
}
|
||||
else
|
||||
{
|
||||
cartridge_Store( );
|
||||
}
|
||||
sally_Reset();
|
||||
region_Reset();
|
||||
tia_Clear();
|
||||
tia_Reset();
|
||||
pokey_Clear();
|
||||
pokey_Reset();
|
||||
memory_Reset();
|
||||
maria_Clear();
|
||||
maria_Reset();
|
||||
riot_Reset();
|
||||
cartridge_LoadHighScoreCart();
|
||||
|
||||
prosystem_cycles = sally_ExecuteRES( );
|
||||
prosystem_active = true;
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// ExecuteFrame
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
|
||||
{
|
||||
static byte last_background = 254;
|
||||
extern int gTotalAtariFrames;
|
||||
extern word *framePtr;
|
||||
bool bRenderScanline = false;
|
||||
cartridge_Store(); // Always call this - it may setup some RAM or other stuff below the BIOS region...
|
||||
|
||||
gTotalAtariFrames++;
|
||||
// Load 7800 BIOS if available... otherwise direct load the CART
|
||||
if(bios_available && !bSkipBIOS)
|
||||
{
|
||||
bios_Store();
|
||||
bios_show_counter = myCartInfo.biosTimeout;
|
||||
}
|
||||
|
||||
riot_SetInput(input);
|
||||
|
||||
for(maria_scanline = 1; maria_scanline <= prosystem_scanlines; maria_scanline++)
|
||||
{
|
||||
if(maria_scanline == maria_displayArea.top)
|
||||
{
|
||||
memory_ram[MSTAT] = 0;
|
||||
framePtr = (word*)(maria_surface + ((maria_scanline - maria_displayArea.top) * 256));
|
||||
bRenderScanline = true;
|
||||
prosystem_cycles = sally_ExecuteRES();
|
||||
}
|
||||
else if(maria_scanline == maria_displayArea.bottom)
|
||||
{
|
||||
memory_ram[MSTAT] = 128;
|
||||
bRenderScanline = false;
|
||||
}
|
||||
|
||||
uint cycles=0;
|
||||
prosystem_cycles %= CYCLES_PER_SCANLINE;
|
||||
sally_Execute(34);
|
||||
|
||||
if (bRenderScanline)
|
||||
{
|
||||
// If our background has changed... set our global 32-bit version of that now... speeds up scanline renders
|
||||
if (memory_ram[BACKGRND] != last_background)
|
||||
{
|
||||
last_background = memory_ram[BACKGRND];
|
||||
bg32 = last_background | (last_background<<8) | (last_background<<16) | (last_background<<24);
|
||||
}
|
||||
cycles = maria_RenderScanline( );
|
||||
}
|
||||
|
||||
if(cartridge_steals_cycles)
|
||||
{
|
||||
prosystem_cycles += cycles;
|
||||
if(riot_timing) riot_UpdateTimer( cycles >> 2 );
|
||||
}
|
||||
|
||||
sally_Execute(CYCLES_PER_SCANLINE);
|
||||
if(cartridge_pokey)
|
||||
{
|
||||
// --------------------------------------------------------------------
|
||||
// If Pokey is enabled, we will only process 1 sample per scanline
|
||||
// instead of the normal 2 as we also have to process the TIA within
|
||||
// that handler and we're already pressed for emulation speed...
|
||||
// This is good enough to get about 16KHz sample rate and on the
|
||||
// DS handheld, it sounds plenty good enough...
|
||||
// --------------------------------------------------------------------
|
||||
pokey_Process(1);
|
||||
pokey_Scanline();
|
||||
} else tia_Process(2); // If all we have to deal with is the TIA, we can do so at 31KHz
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pause
|
||||
// ExecuteFrame - this is hand-tuned for NTSC output with hard-coded
|
||||
// NTSC frame values ... this will not work properly if a PAL ROM is used.
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Pause(bool pause) {
|
||||
if(prosystem_active) {
|
||||
prosystem_paused = pause;
|
||||
}
|
||||
ITCM_CODE void prosystem_ExecuteFrame(const byte * input)
|
||||
{
|
||||
extern u16 gTotalAtariFrames;
|
||||
extern word * framePtr;
|
||||
extern uint maria_cycles;
|
||||
|
||||
gTotalAtariFrames++;
|
||||
bRenderFrame = 0;
|
||||
|
||||
riot_SetInput(input);
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Handle the VERTICAL BLANK area first... speeds up processing below...
|
||||
// ---------------------------------------------------------------------
|
||||
memory_ram[MSTAT] = 128; // Into the Vertical Blank...
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Note: this is not accurate. It should be 263 scanlines total but it doesn't work for all
|
||||
// games at 263 so we've gone with 262 for maximum compatibility. This is likely due to some
|
||||
// emulation cycle counting inaccuracies. At 263, some games run too fast (Asteroids, Deluxe)
|
||||
// and some crash (Robotron) and some issues with Pole Position II and the joystick selection
|
||||
// of a course to play. I've also seen graphical glitches in Crossbow when loaded via the
|
||||
// BIOS and all kinds of graphical oddities in Xenophobe. Be very careful if you change this...
|
||||
// be sure you understand the consequences (and this developer doesn't... so be warned!).
|
||||
// -------------------------------------------------------------------------------------------
|
||||
for(maria_scanline = 1; maria_scanline <= 21; maria_scanline++)
|
||||
{
|
||||
prosystem_cycles = 0;
|
||||
|
||||
if(maria_scanline == 21) // Maria can start to do her thing... We've had 20 VBLANK scanlines
|
||||
{
|
||||
memory_ram[MSTAT] = 0; // Out of the vertical blank
|
||||
framePtr = (word * )(maria_surface);
|
||||
sally_Execute(CYCLES_BEFORE_DMA);
|
||||
|
||||
maria_RenderScanlineTOP();
|
||||
|
||||
// Cycle Stealing happens here...
|
||||
prosystem_cycles += ((maria_cycles + 3) >> 2) << 2; // Always a multiple of 4
|
||||
if(riot_and_wsync & 2) riot_UpdateTimer(maria_cycles >> 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
sally_Execute(CYCLES_BEFORE_DMA);
|
||||
}
|
||||
|
||||
sally_Execute(CYCLES_PER_SCANLINE);
|
||||
|
||||
if(myCartInfo.pokeyType) // If pokey enabled, we process 1 pokey sample and 1 TIA sample. Good enough.
|
||||
{
|
||||
pokey_Process();
|
||||
pokey_Scanline();
|
||||
}
|
||||
else tia_Process(); // If all we have to deal with is the TIA, we can do so at 31KHz
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Now handle the Main display area...
|
||||
// ------------------------------------------------------------
|
||||
for(; maria_scanline < 263; maria_scanline++)
|
||||
{
|
||||
prosystem_cycles = 0;
|
||||
|
||||
if(maria_scanline >= 30)
|
||||
{
|
||||
// --------------------------------------------------------------------------
|
||||
// We can start to render the scanlines if we are not skipping this frame.
|
||||
// The DS/DSi only has 192 vertical pixels and we can perform some hardware
|
||||
// scaling but there is a point at which we really can't show any more lines.
|
||||
// To that end, we'll render ~223 lines which is good enough for most games.
|
||||
// If a game uses more overscan area - those scanlines won't show on screen.
|
||||
// ---------------------------------------------------------------------------
|
||||
if(maria_scanline >= 253)
|
||||
{
|
||||
bRenderFrame = 0; // We can stop rendering frames... DS can't show it anyway with limited vertical resolution.
|
||||
}
|
||||
else
|
||||
{
|
||||
bRenderFrame = gTotalAtariFrames & frameSkipMask;
|
||||
}
|
||||
}
|
||||
|
||||
sally_Execute(CYCLES_BEFORE_DMA);
|
||||
|
||||
maria_RenderScanline();
|
||||
|
||||
// Cycle Stealing happens here...
|
||||
prosystem_cycles += ((maria_cycles + 3) >> 2) << 2; // Always a multiple of 4
|
||||
if(riot_and_wsync & 2) riot_UpdateTimer(maria_cycles >> 2);
|
||||
|
||||
sally_Execute(CYCLES_PER_SCANLINE);
|
||||
|
||||
if(myCartInfo.pokeyType) // If pokey enabled, we process 1 pokey sample and 1 TIA sample. Good enough.
|
||||
{
|
||||
pokey_Process();
|
||||
pokey_Scanline();
|
||||
}
|
||||
else tia_Process(); // If all we have to deal with is the TIA, we can do so at 31KHz
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Close
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Close( ) {
|
||||
prosystem_active = false;
|
||||
prosystem_paused = false;
|
||||
cartridge_Release( );
|
||||
maria_Reset( );
|
||||
maria_Clear( );
|
||||
memory_Reset( );
|
||||
tia_Reset( );
|
||||
tia_Clear( );
|
||||
void prosystem_Close()
|
||||
{
|
||||
cartridge_Release();
|
||||
maria_Reset();
|
||||
maria_Clear();
|
||||
memory_Reset();
|
||||
tia_Reset();
|
||||
tia_Clear();
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "Equates.h"
|
||||
#include "Bios.h"
|
||||
#include "Cartridge.h"
|
||||
#include "HighScore.h"
|
||||
#include "Maria.h"
|
||||
|
@ -36,19 +35,19 @@
|
|||
#include "Region.h"
|
||||
#include "Riot.h"
|
||||
#include "Sally.h"
|
||||
#include "Archive.h"
|
||||
#include "Tia.h"
|
||||
#include "Pokey.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
//#define KANGAROO_MODE_SUPPORTED YES // Uncomment this for KANGAROO support. Slightly slower and virtually no game uses it... but more accurate
|
||||
//#define DS_LITE 1 // Uncomment this for a very stripped-down version that has very low compaitibility but will run fast enough on the DS_LITE
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#define RAM_MIRRORS_ENABLED 1 // Uncomment if you want to have RAM mirrors handled (slower and no games need it as of this writing)
|
||||
|
||||
extern int debug[];
|
||||
|
||||
// The number of cycles per scan line
|
||||
#define CYCLES_PER_SCANLINE 454
|
||||
extern u8 isDS_LITE;
|
||||
extern u8 bSkipBIOS;
|
||||
|
||||
// Difficulty switches...
|
||||
#define DIFF_A 0
|
||||
|
@ -56,13 +55,10 @@ extern int debug[];
|
|||
|
||||
extern void prosystem_Reset( );
|
||||
extern void prosystem_ExecuteFrame(const byte* input);
|
||||
extern void prosystem_Pause(bool pause);
|
||||
extern void prosystem_Close( );
|
||||
extern bool prosystem_active;
|
||||
extern bool prosystem_paused;
|
||||
extern word prosystem_frequency;
|
||||
extern byte prosystem_frame;
|
||||
extern word prosystem_scanlines;
|
||||
extern uint prosystem_cycles;
|
||||
extern void Trace(word data);
|
||||
extern void Trace2(word addr, u8 data);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rect.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef RECT_H
|
||||
#define RECT_H
|
||||
|
||||
typedef struct {
|
||||
uint left;
|
||||
uint top;
|
||||
uint right;
|
||||
uint bottom;
|
||||
|
||||
uint GetArea;
|
||||
uint GetLength;
|
||||
uint GetHeight;
|
||||
} Rect ;
|
||||
|
||||
typedef Rect rect;
|
||||
#endif
|
||||
|
|
@ -20,266 +20,223 @@
|
|||
// 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"
|
||||
|
||||
byte region_type = REGION_AUTO;
|
||||
|
||||
static const rect REGION_DISPLAY_AREA_NTSC = {0, 16, 319, 258};
|
||||
static const rect REGION_VISIBLE_AREA_NTSC = {0, 26, 319, 250};
|
||||
|
||||
static const byte REGION_FREQUENCY_NTSC = 60;
|
||||
static const word REGION_SCANLINES_NTSC = 262;
|
||||
|
||||
static const rect REGION_DISPLAY_AREA_PAL = {0, 16, 319, 308};
|
||||
static const rect REGION_VISIBLE_AREA_PAL = {0, 26, 319, 297};
|
||||
static const byte REGION_FREQUENCY_PAL = 50;
|
||||
static const word REGION_SCANLINES_PAL = 312;
|
||||
#include "Database.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PALETTE NTSC
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const byte REGION_PALETTE_NTSC[ ] = {
|
||||
0x00,0x00,0x00,0x25,0x25,0x25,0x34,0x34,0x34,0x4F,0x4F,0x4F,
|
||||
0x5B,0x5B,0x5B,0x69,0x69,0x69,0x7B,0x7B,0x7B,0x8A,0x8A,0x8A,
|
||||
0xA7,0xA7,0xA7,0xB9,0xB9,0xB9,0xC5,0xC5,0xC5,0xD0,0xD0,0xD0,
|
||||
0xD7,0xD7,0xD7,0xE1,0xE1,0xE1,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,
|
||||
0x4C,0x32,0x00,0x62,0x3A,0x00,0x7B,0x4A,0x00,0x9A,0x60,0x00,
|
||||
0xB5,0x74,0x00,0xCC,0x85,0x00,0xE7,0x9E,0x08,0xF7,0xAF,0x10,
|
||||
0xFF,0xC3,0x18,0xFF,0xD0,0x20,0xFF,0xD8,0x28,0xFF,0xDF,0x30,
|
||||
0xFF,0xE6,0x3B,0xFF,0xF4,0x40,0xFF,0xFA,0x4B,0xFF,0xFF,0x50,
|
||||
0x99,0x25,0x00,0xAA,0x25,0x00,0xB4,0x25,0x00,0xD3,0x30,0x00,
|
||||
0xDD,0x48,0x02,0xE2,0x50,0x09,0xF4,0x67,0x00,0xF4,0x75,0x10,
|
||||
0xFF,0x9E,0x10,0xFF,0xAC,0x20,0xFF,0xBA,0x3A,0xFF,0xBF,0x50,
|
||||
0xFF,0xC6,0x6D,0xFF,0xD5,0x80,0xFF,0xE4,0x90,0xFF,0xE6,0x99,
|
||||
0x98,0x0C,0x0C,0x99,0x0C,0x0C,0xC2,0x13,0x00,0xD3,0x13,0x00,
|
||||
0xE2,0x35,0x00,0xE3,0x40,0x00,0xE4,0x40,0x20,0xE5,0x52,0x30,
|
||||
0xFD,0x78,0x54,0xFF,0x8A,0x6A,0xFF,0x98,0x7C,0xFF,0xA4,0x8B,
|
||||
0xFF,0xB3,0x9E,0xFF,0xC2,0xB2,0xFF,0xD0,0xBA,0xFF,0xD7,0xC0,
|
||||
0x99,0x00,0x00,0xA9,0x00,0x00,0xC2,0x04,0x00,0xD3,0x04,0x00,
|
||||
0xDA,0x04,0x00,0xDB,0x08,0x00,0xE4,0x20,0x20,0xF6,0x40,0x40,
|
||||
0xFB,0x70,0x70,0xFB,0x7E,0x7E,0xFB,0x8F,0x8F,0xFF,0x9F,0x9F,
|
||||
0xFF,0xAB,0xAB,0xFF,0xB9,0xB9,0xFF,0xC9,0xC9,0xFF,0xCF,0xCF,
|
||||
0x7E,0x00,0x50,0x80,0x00,0x50,0x80,0x00,0x5F,0x95,0x0B,0x74,
|
||||
0xAA,0x22,0x88,0xBB,0x2F,0x9A,0xCE,0x3F,0xAD,0xD7,0x5A,0xB6,
|
||||
0xE4,0x67,0xC3,0xEF,0x72,0xCE,0xFB,0x7E,0xDA,0xFF,0x8D,0xE1,
|
||||
0xFF,0x9D,0xE5,0xFF,0xA5,0xE7,0xFF,0xAF,0xEA,0xFF,0xB8,0xEC,
|
||||
0x48,0x00,0x6C,0x5C,0x04,0x88,0x65,0x0D,0x90,0x7B,0x23,0xA7,
|
||||
0x93,0x3B,0xBF,0x9D,0x45,0xC9,0xA7,0x4F,0xD3,0xB2,0x5A,0xDE,
|
||||
0xBD,0x65,0xE9,0xC5,0x6D,0xF1,0xCE,0x76,0xFA,0xD5,0x83,0xFF,
|
||||
0xDA,0x90,0xFF,0xDE,0x9C,0xFF,0xE2,0xA9,0xFF,0xE6,0xB6,0xFF,
|
||||
0x1B,0x00,0x70,0x22,0x1B,0x8D,0x37,0x30,0xA2,0x48,0x41,0xB3,
|
||||
0x59,0x52,0xC4,0x63,0x5C,0xCE,0x6F,0x68,0xDA,0x7D,0x76,0xE8,
|
||||
0x87,0x80,0xF8,0x93,0x8C,0xFF,0x9D,0x97,0xFF,0xA8,0xA3,0xFF,
|
||||
0xB3,0xAF,0xFF,0xBC,0xB8,0xFF,0xC4,0xC1,0xFF,0xDA,0xD1,0xFF,
|
||||
0x00,0x0D,0x7F,0x00,0x12,0xA7,0x00,0x18,0xC0,0x0A,0x2B,0xD1,
|
||||
0x1B,0x4A,0xE3,0x2F,0x58,0xF0,0x37,0x68,0xFF,0x49,0x79,0xFF,
|
||||
0x5B,0x85,0xFF,0x6D,0x96,0xFF,0x7F,0xA3,0xFF,0x8C,0xAD,0xFF,
|
||||
0x96,0xB4,0xFF,0xA8,0xC0,0xFF,0xB7,0xCB,0xFF,0xC6,0xD6,0xFF,
|
||||
0x00,0x29,0x5A,0x00,0x38,0x76,0x00,0x48,0x92,0x00,0x5C,0xAC,
|
||||
0x00,0x71,0xC6,0x00,0x86,0xD0,0x0A,0x9B,0xDF,0x1A,0xA8,0xEC,
|
||||
0x2B,0xB6,0xFF,0x3F,0xC2,0xFF,0x45,0xCB,0xFF,0x59,0xD3,0xFF,
|
||||
0x7F,0xDA,0xFF,0x8F,0xDE,0xFF,0xA0,0xE2,0xFF,0xB0,0xEB,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x4C,0x00,0x00,0x6A,0x20,0x50,0x8E,0x79,
|
||||
0x40,0x99,0x99,0x00,0x9C,0xAA,0x00,0xA1,0xBB,0x01,0xA4,0xCC,
|
||||
0x03,0xA5,0xD7,0x05,0xDA,0xE2,0x18,0xE5,0xFF,0x34,0xEA,0xFF,
|
||||
0x49,0xEF,0xFF,0x66,0xF2,0xFF,0x84,0xF4,0xFF,0x9E,0xF9,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x5D,0x00,0x00,0x70,0x00,0x00,0x83,0x00,
|
||||
0x00,0x95,0x00,0x00,0xAB,0x00,0x07,0xBD,0x07,0x0A,0xD0,0x0A,
|
||||
0x1A,0xD5,0x40,0x5A,0xF1,0x77,0x82,0xEF,0xA7,0x84,0xED,0xD1,
|
||||
0x89,0xFF,0xED,0x7D,0xFF,0xFF,0x93,0xFF,0xFF,0x9B,0xFF,0xFF,
|
||||
0x22,0x4A,0x03,0x27,0x53,0x04,0x30,0x64,0x05,0x3C,0x77,0x0C,
|
||||
0x45,0x8C,0x11,0x5A,0xA5,0x13,0x1B,0xD2,0x09,0x1F,0xDD,0x00,
|
||||
0x3D,0xCD,0x2D,0x3D,0xCD,0x30,0x58,0xCC,0x40,0x60,0xD3,0x50,
|
||||
0xA2,0xEC,0x55,0xB3,0xF2,0x4A,0xBB,0xF6,0x5D,0xC4,0xF8,0x70,
|
||||
0x2E,0x3F,0x0C,0x36,0x4A,0x0F,0x40,0x56,0x15,0x46,0x5F,0x17,
|
||||
0x57,0x77,0x1A,0x65,0x85,0x1C,0x74,0x93,0x1D,0x8F,0xA5,0x25,
|
||||
0xAD,0xB7,0x2C,0xBC,0xC7,0x30,0xC9,0xD5,0x33,0xD4,0xE0,0x3B,
|
||||
0xE0,0xEC,0x42,0xEA,0xF6,0x45,0xF0,0xFD,0x47,0xF4,0xFF,0x6F,
|
||||
0x55,0x24,0x00,0x5A,0x2C,0x00,0x6C,0x3B,0x00,0x79,0x4B,0x00,
|
||||
0xB9,0x75,0x00,0xBB,0x85,0x00,0xC1,0xA1,0x20,0xD0,0xB0,0x2F,
|
||||
0xDE,0xBE,0x3F,0xE6,0xC6,0x45,0xED,0xCD,0x57,0xF5,0xDB,0x62,
|
||||
0xFB,0xE5,0x69,0xFC,0xEE,0x6F,0xFD,0xF3,0x77,0xFD,0xF3,0x7F,
|
||||
0x5C,0x27,0x00,0x5C,0x2F,0x00,0x71,0x3B,0x00,0x7B,0x48,0x00,
|
||||
0xB9,0x68,0x20,0xBB,0x72,0x20,0xC5,0x86,0x29,0xD7,0x96,0x33,
|
||||
0xE6,0xA4,0x40,0xF4,0xB1,0x4B,0xFD,0xC1,0x58,0xFF,0xCC,0x55,
|
||||
0xFF,0xD4,0x61,0xFF,0xDD,0x69,0xFF,0xE6,0x79,0xFF,0xEA,0x98
|
||||
const byte REGION_PALETTE_NTSC_CRT_COOL[ ] = {
|
||||
0x00, 0x00, 0x00, 0x0d, 0x0d, 0x0d, 0x28, 0x28, 0x28, 0x3e, 0x3e, 0x3e,
|
||||
0x52, 0x52, 0x52, 0x65, 0x65, 0x65, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88,
|
||||
0x98, 0x98, 0x98, 0xa8, 0xa8, 0xa8, 0xb7, 0xb7, 0xb7, 0xc6, 0xc6, 0xc6,
|
||||
0xd5, 0xd5, 0xd5, 0xe3, 0xe3, 0xe3, 0xf1, 0xf1, 0xf1, 0xff, 0xff, 0xff,
|
||||
0x42, 0x28, 0x00, 0x54, 0x3d, 0x00, 0x65, 0x4f, 0x00, 0x75, 0x60, 0x00,
|
||||
0x84, 0x70, 0x00, 0x93, 0x80, 0x00, 0xa2, 0x8f, 0x00, 0xb0, 0x9d, 0x00,
|
||||
0xbe, 0xac, 0x00, 0xcb, 0xb9, 0x00, 0xd8, 0xc7, 0x00, 0xe5, 0xd4, 0x1a,
|
||||
0xf2, 0xe1, 0x30, 0xfe, 0xee, 0x43, 0xff, 0xfb, 0x55, 0xff, 0xff, 0x66,
|
||||
0x6c, 0x0f, 0x00, 0x7b, 0x28, 0x00, 0x8a, 0x3c, 0x00, 0x99, 0x4e, 0x00,
|
||||
0xa7, 0x60, 0x00, 0xb5, 0x70, 0x00, 0xc3, 0x7f, 0x00, 0xd0, 0x8e, 0x00,
|
||||
0xdd, 0x9d, 0x00, 0xea, 0xab, 0x1c, 0xf7, 0xb9, 0x32, 0xff, 0xc7, 0x45,
|
||||
0xff, 0xd4, 0x57, 0xff, 0xe1, 0x68, 0xff, 0xee, 0x78, 0xff, 0xfa, 0x87,
|
||||
0x84, 0x00, 0x00, 0x93, 0x11, 0x00, 0xa1, 0x29, 0x00, 0xaf, 0x3d, 0x00,
|
||||
0xbd, 0x4f, 0x00, 0xca, 0x60, 0x18, 0xd7, 0x71, 0x2f, 0xe4, 0x80, 0x42,
|
||||
0xf1, 0x8f, 0x54, 0xfe, 0x9e, 0x65, 0xff, 0xac, 0x75, 0xff, 0xba, 0x85,
|
||||
0xff, 0xc7, 0x93, 0xff, 0xd4, 0xa2, 0xff, 0xe1, 0xb0, 0xff, 0xee, 0xbe,
|
||||
0x89, 0x00, 0x14, 0x98, 0x00, 0x2c, 0xa6, 0x19, 0x40, 0xb4, 0x2f, 0x52,
|
||||
0xc2, 0x43, 0x63, 0xcf, 0x55, 0x73, 0xdc, 0x65, 0x82, 0xe9, 0x75, 0x91,
|
||||
0xf6, 0x85, 0xa0, 0xff, 0x94, 0xae, 0xff, 0xa2, 0xbc, 0xff, 0xb0, 0xc9,
|
||||
0xff, 0xbe, 0xd6, 0xff, 0xcb, 0xe3, 0xff, 0xd8, 0xf0, 0xff, 0xe5, 0xfd,
|
||||
0x7c, 0x00, 0x71, 0x8c, 0x00, 0x80, 0x9a, 0x11, 0x8f, 0xa8, 0x29, 0x9e,
|
||||
0xb6, 0x3d, 0xac, 0xc4, 0x4f, 0xba, 0xd1, 0x61, 0xc7, 0xde, 0x71, 0xd5,
|
||||
0xeb, 0x80, 0xe2, 0xf8, 0x8f, 0xee, 0xff, 0x9e, 0xfb, 0xff, 0xac, 0xff,
|
||||
0xff, 0xba, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xd5, 0xff, 0xff, 0xe2, 0xff,
|
||||
0x5d, 0x00, 0xac, 0x6e, 0x00, 0xb9, 0x7e, 0x15, 0xc7, 0x8d, 0x2d, 0xd4,
|
||||
0x9b, 0x40, 0xe1, 0xa9, 0x52, 0xee, 0xb7, 0x63, 0xfb, 0xc5, 0x73, 0xff,
|
||||
0xd2, 0x83, 0xff, 0xdf, 0x92, 0xff, 0xec, 0xa0, 0xff, 0xf9, 0xae, 0xff,
|
||||
0xff, 0xbc, 0xff, 0xff, 0xca, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xe4, 0xff,
|
||||
0x2d, 0x00, 0xca, 0x41, 0x0a, 0xd7, 0x53, 0x24, 0xe4, 0x64, 0x39, 0xf1,
|
||||
0x74, 0x4b, 0xfe, 0x83, 0x5d, 0xff, 0x92, 0x6d, 0xff, 0xa1, 0x7d, 0xff,
|
||||
0xaf, 0x8c, 0xff, 0xbd, 0x9a, 0xff, 0xca, 0xa9, 0xff, 0xd7, 0xb7, 0xff,
|
||||
0xe4, 0xc4, 0xff, 0xf1, 0xd1, 0xff, 0xfd, 0xdf, 0xff, 0xff, 0xeb, 0xff,
|
||||
0x00, 0x06, 0xcc, 0x00, 0x21, 0xd9, 0x1c, 0x37, 0xe6, 0x32, 0x49, 0xf2,
|
||||
0x45, 0x5b, 0xff, 0x57, 0x6b, 0xff, 0x67, 0x7b, 0xff, 0x77, 0x8a, 0xff,
|
||||
0x87, 0x99, 0xff, 0x95, 0xa7, 0xff, 0xa4, 0xb5, 0xff, 0xb2, 0xc3, 0xff,
|
||||
0xbf, 0xd0, 0xff, 0xcd, 0xdd, 0xff, 0xda, 0xea, 0xff, 0xe7, 0xf7, 0xff,
|
||||
0x00, 0x22, 0xb0, 0x00, 0x37, 0xbd, 0x00, 0x4a, 0xcb, 0x00, 0x5b, 0xd8,
|
||||
0x11, 0x6c, 0xe5, 0x29, 0x7c, 0xf2, 0x3d, 0x8b, 0xfe, 0x4f, 0x99, 0xff,
|
||||
0x61, 0xa8, 0xff, 0x71, 0xb6, 0xff, 0x80, 0xc3, 0xff, 0x8f, 0xd1, 0xff,
|
||||
0x9e, 0xde, 0xff, 0xac, 0xea, 0xff, 0xba, 0xf7, 0xff, 0xc7, 0xff, 0xff,
|
||||
0x00, 0x36, 0x77, 0x00, 0x49, 0x87, 0x00, 0x5b, 0x96, 0x00, 0x6b, 0xa4,
|
||||
0x00, 0x7b, 0xb2, 0x00, 0x8a, 0xc0, 0x1c, 0x99, 0xcd, 0x32, 0xa7, 0xda,
|
||||
0x45, 0xb5, 0xe7, 0x57, 0xc3, 0xf4, 0x68, 0xd0, 0xff, 0x78, 0xdd, 0xff,
|
||||
0x87, 0xea, 0xff, 0x96, 0xf7, 0xff, 0xa4, 0xff, 0xff, 0xb2, 0xff, 0xff,
|
||||
0x00, 0x44, 0x20, 0x00, 0x55, 0x35, 0x00, 0x66, 0x48, 0x00, 0x76, 0x5a,
|
||||
0x00, 0x86, 0x6a, 0x00, 0x94, 0x7a, 0x12, 0xa3, 0x89, 0x2a, 0xb1, 0x98,
|
||||
0x3e, 0xbf, 0xa6, 0x50, 0xcc, 0xb4, 0x61, 0xd9, 0xc2, 0x71, 0xe6, 0xcf,
|
||||
0x81, 0xf3, 0xdc, 0x90, 0xff, 0xe9, 0x9f, 0xff, 0xf6, 0xad, 0xff, 0xff,
|
||||
0x00, 0x49, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x7b, 0x00,
|
||||
0x00, 0x8a, 0x08, 0x0e, 0x99, 0x22, 0x26, 0xa7, 0x37, 0x3b, 0xb5, 0x4a,
|
||||
0x4d, 0xc3, 0x5b, 0x5f, 0xd0, 0x6c, 0x6f, 0xdd, 0x7c, 0x7f, 0xea, 0x8b,
|
||||
0x8e, 0xf7, 0x9a, 0x9c, 0xff, 0xa8, 0xaa, 0xff, 0xb6, 0xb8, 0xff, 0xc3,
|
||||
0x00, 0x46, 0x00, 0x00, 0x58, 0x00, 0x00, 0x68, 0x00, 0x0b, 0x78, 0x00,
|
||||
0x25, 0x88, 0x00, 0x39, 0x96, 0x00, 0x4c, 0xa5, 0x00, 0x5d, 0xb3, 0x00,
|
||||
0x6e, 0xc0, 0x08, 0x7d, 0xce, 0x23, 0x8c, 0xdb, 0x38, 0x9b, 0xe8, 0x4a,
|
||||
0xa9, 0xf5, 0x5c, 0xb7, 0xff, 0x6c, 0xc5, 0xff, 0x7c, 0xd2, 0xff, 0x8b,
|
||||
0x00, 0x3b, 0x00, 0x1c, 0x4e, 0x00, 0x32, 0x5f, 0x00, 0x45, 0x6f, 0x00,
|
||||
0x57, 0x7f, 0x00, 0x67, 0x8e, 0x00, 0x77, 0x9c, 0x00, 0x87, 0xab, 0x00,
|
||||
0x95, 0xb8, 0x00, 0xa4, 0xc6, 0x00, 0xb2, 0xd3, 0x00, 0xbf, 0xe0, 0x1c,
|
||||
0xcd, 0xed, 0x32, 0xda, 0xfa, 0x45, 0xe7, 0xff, 0x57, 0xf4, 0xff, 0x68,
|
||||
0x41, 0x29, 0x00, 0x53, 0x3d, 0x00, 0x64, 0x4f, 0x00, 0x74, 0x61, 0x00,
|
||||
0x83, 0x71, 0x00, 0x92, 0x80, 0x00, 0xa1, 0x8f, 0x00, 0xaf, 0x9e, 0x00,
|
||||
0xbd, 0xac, 0x00, 0xca, 0xba, 0x00, 0xd7, 0xc7, 0x00, 0xe4, 0xd5, 0x19,
|
||||
0xf1, 0xe2, 0x30, 0xfd, 0xee, 0x43, 0xff, 0xfb, 0x55, 0xff, 0xff, 0x66
|
||||
};
|
||||
|
||||
#if 0
|
||||
// 1.2
|
||||
static const byte REGION_PALETTE_NTSC[ ] = {
|
||||
0x00,0x00,0x00,0x25,0x25,0x25,0x34,0x34,0x34,0x4F,0x4F,0x4F,
|
||||
0x5B,0x5B,0x5B,0x69,0x69,0x69,0x7B,0x7B,0x7B,0x8A,0x8A,0x8A,
|
||||
0xA7,0xA7,0xA7,0xB9,0xB9,0xB9,0xC5,0xC5,0xC5,0xD0,0xD0,0xD0,
|
||||
0xD7,0xD7,0xD7,0xE1,0xE1,0xE1,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,
|
||||
0x4C,0x32,0x00,0x62,0x3A,0x00,0x7B,0x4A,0x00,0x9A,0x60,0x00,
|
||||
0xB5,0x74,0x00,0xCC,0x85,0x00,0xE7,0x9E,0x08,0xF7,0xAF,0x10,
|
||||
0xFF,0xC3,0x18,0xFF,0xD0,0x20,0xFF,0xD8,0x28,0xFF,0xDF,0x30,
|
||||
0xFF,0xE6,0x3B,0xFF,0xF4,0x40,0xFF,0xFA,0x4B,0xFF,0xFF,0x50,
|
||||
0x99,0x25,0x00,0xAA,0x25,0x00,0xB4,0x25,0x00,0xD3,0x30,0x00,
|
||||
0xDD,0x48,0x02,0xE2,0x50,0x09,0xF4,0x67,0x00,0xF4,0x71,0x00,
|
||||
0xFF,0x9E,0x10,0xFF,0xAC,0x20,0xFF,0xBA,0x3A,0xFF,0xBF,0x50,
|
||||
0xFF,0xC6,0x6D,0xFF,0xD5,0x80,0xFF,0xE4,0x90,0xFF,0xE6,0x99,
|
||||
0x99,0x00,0x00,0xA9,0x00,0x00,0xC6,0x13,0x00,0xD8,0x04,0x00,
|
||||
0xE2,0x35,0x00,0xE4,0x40,0x00,0xE3,0x50,0x15,0xE3,0x52,0x25,
|
||||
0xFD,0x78,0x54,0xFF,0x8A,0x6A,0xFF,0x98,0x7C,0xFF,0xA4,0x8B,
|
||||
0xFF,0xB3,0x9E,0xFF,0xC2,0xB2,0xFF,0xD0,0xBA,0xFF,0xD7,0xC0,
|
||||
0x98,0x0C,0x0C,0xA7,0x0D,0x0D,0xAA,0x15,0x15,0xAA,0x20,0x25,
|
||||
0xD2,0x1A,0x30,0xD3,0x28,0x00,0xD5,0x27,0x10,0xD6,0x27,0x30,
|
||||
0xFB,0x70,0x70,0xFB,0x7E,0x7E,0xFB,0x8F,0x8F,0xFF,0x9F,0x9F,
|
||||
0xFF,0xAB,0xAB,0xFF,0xB9,0xB9,0xFF,0xC9,0xC9,0xFF,0xCF,0xCF,
|
||||
0x7E,0x00,0x50,0x80,0x00,0x50,0x80,0x00,0x5F,0x95,0x0B,0x74,
|
||||
0xAA,0x22,0x88,0xBB,0x2F,0x9A,0xCE,0x3F,0xAD,0xD7,0x5A,0xB6,
|
||||
0xE4,0x67,0xC3,0xEF,0x72,0xCE,0xFB,0x7E,0xDA,0xFF,0x8D,0xE1,
|
||||
0xFF,0x9D,0xE5,0xFF,0xA5,0xE7,0xFF,0xAF,0xEA,0xFF,0xB8,0xEC,
|
||||
0x48,0x00,0x6C,0x5C,0x04,0x88,0x65,0x0D,0x90,0x7B,0x23,0xA7,
|
||||
0x93,0x3B,0xBF,0x9D,0x45,0xC9,0xA7,0x4F,0xD3,0xB2,0x5A,0xDE,
|
||||
0xBD,0x65,0xE9,0xC5,0x6D,0xF1,0xCE,0x76,0xFA,0xD5,0x83,0xFF,
|
||||
0xDA,0x90,0xFF,0xDE,0x9C,0xFF,0xE2,0xA9,0xFF,0xE6,0xB6,0xFF,
|
||||
0x1B,0x00,0x70,0x22,0x1B,0x8D,0x37,0x30,0xA2,0x48,0x41,0xB3,
|
||||
0x59,0x52,0xC4,0x63,0x5C,0xCE,0x6F,0x68,0xDA,0x7D,0x76,0xE8,
|
||||
0x87,0x80,0xF8,0x93,0x8C,0xFF,0x9D,0x97,0xFF,0xA8,0xA3,0xFF,
|
||||
0xB3,0xAF,0xFF,0xBC,0xB8,0xFF,0xC4,0xC1,0xFF,0xDA,0xD1,0xFF,
|
||||
0x00,0x0D,0x7F,0x00,0x12,0xA7,0x00,0x18,0xC0,0x0A,0x2B,0xD1,
|
||||
0x1B,0x4A,0xE3,0x2F,0x58,0xF0,0x37,0x68,0xFF,0x49,0x79,0xFF,
|
||||
0x5B,0x85,0xFF,0x6D,0x96,0xFF,0x7F,0xA3,0xFF,0x8C,0xAD,0xFF,
|
||||
0x96,0xB4,0xFF,0xA8,0xC0,0xFF,0xB7,0xCB,0xFF,0xC6,0xD6,0xFF,
|
||||
0x00,0x29,0x5A,0x00,0x38,0x76,0x00,0x48,0x92,0x00,0x5C,0xAC,
|
||||
0x00,0x71,0xC6,0x00,0x86,0xD0,0x0A,0x9B,0xDF,0x1A,0xA8,0xEC,
|
||||
0x2B,0xB6,0xFF,0x3F,0xC2,0xFF,0x45,0xCB,0xFF,0x59,0xD3,0xFF,
|
||||
0x7F,0xDA,0xFF,0x8F,0xDE,0xFF,0xA0,0xE2,0xFF,0xB0,0xEB,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x4C,0x00,0x00,0x6A,0x20,0x50,0x8E,0x79,
|
||||
0x40,0x99,0x99,0x00,0x9C,0xAA,0x00,0xA1,0xBB,0x01,0xA4,0xCC,
|
||||
0x03,0xA5,0xD7,0x05,0xDA,0xE2,0x18,0xE5,0xFF,0x34,0xEA,0xFF,
|
||||
0x49,0xEF,0xFF,0x66,0xF2,0xFF,0x84,0xF4,0xFF,0x9E,0xF9,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x5D,0x00,0x00,0x70,0x00,0x00,0x83,0x00,
|
||||
0x00,0x95,0x00,0x00,0xAB,0x00,0x07,0xBD,0x07,0x0A,0xD0,0x0A,
|
||||
0x1A,0xD5,0x40,0x5A,0xF1,0x77,0x82,0xEF,0xA7,0x84,0xED,0xD1,
|
||||
0x89,0xFF,0xED,0x7D,0xFF,0xFF,0x93,0xFF,0xFF,0x9B,0xFF,0xFF,
|
||||
0x22,0x4A,0x03,0x27,0x53,0x04,0x30,0x64,0x05,0x3C,0x77,0x0C,
|
||||
0x45,0x8C,0x11,0x5A,0xA5,0x13,0x1B,0xD2,0x09,0x1F,0xDD,0x00,
|
||||
0x3D,0xCD,0x2D,0x3D,0xCD,0x30,0x58,0xCC,0x40,0x60,0xD3,0x50,
|
||||
0xA2,0xEC,0x55,0xB3,0xF2,0x4A,0xBB,0xF6,0x5D,0xC4,0xF8,0x70,
|
||||
0x2E,0x3F,0x0C,0x36,0x4A,0x0F,0x40,0x56,0x15,0x46,0x5F,0x17,
|
||||
0x57,0x77,0x1A,0x65,0x85,0x1C,0x74,0x93,0x1D,0x8F,0xA5,0x25,
|
||||
0xAD,0xB7,0x2C,0xBC,0xC7,0x30,0xC9,0xD5,0x33,0xD4,0xE0,0x3B,
|
||||
0xE0,0xEC,0x42,0xEA,0xF6,0x45,0xF0,0xFD,0x47,0xF4,0xFF,0x6F,
|
||||
0x5A,0x24,0x00,0x55,0x24,0x00,0x64,0x2D,0x06,0x92,0x55,0x2B,
|
||||
0x9F,0x66,0x20,0xBB,0x85,0x00,0xC1,0xA1,0x20,0xD0,0xB0,0x2F,
|
||||
0xDE,0xBE,0x3F,0xE6,0xC6,0x45,0xED,0xCD,0x57,0xF5,0xDB,0x62,
|
||||
0xFB,0xE5,0x69,0xFC,0xEE,0x6F,0xFD,0xF3,0x77,0xFD,0xF3,0x7F,
|
||||
0x5C,0x27,0x00,0x5C,0x27,0x00,0x75,0x2D,0x06,0x92,0x48,0x08,
|
||||
0x92,0x50,0x18,0xBB,0x72,0x20,0xC5,0x86,0x29,0xD7,0x96,0x33,
|
||||
0xE6,0xA4,0x40,0xF4,0xB1,0x4B,0xFD,0xC1,0x58,0xFF,0xCC,0x55,
|
||||
0xFF,0xD4,0x61,0xFF,0xDD,0x69,0xFF,0xE6,0x79,0xFF,0xEA,0x98
|
||||
};
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// PALETTE PAL
|
||||
// --------------------------------------------------------------------------------------
|
||||
const byte REGION_PALETTE_PAL[ ] = {
|
||||
0x00,0x00,0x00,0x1c,0x1c,0x1c,0x39,0x39,0x39,0x59,0x59,0x59,
|
||||
0x79,0x79,0x79,0x92,0x92,0x92,0xab,0xab,0xab,0xbc,0xbc,0xbc,
|
||||
0xcd,0xcd,0xcd,0xd9,0xd9,0xd9,0xe6,0xe6,0xe6,0xec,0xec,0xec,
|
||||
0xf2,0xf2,0xf2,0xf8,0xf8,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x26,0x30,0x01,0x24,0x38,0x03,0x23,0x40,0x05,0x51,0x54,0x1b,
|
||||
0x80,0x69,0x31,0x97,0x81,0x35,0xaf,0x99,0x3a,0xc2,0xa7,0x3e,
|
||||
0xd5,0xb5,0x43,0xdb,0xc0,0x3d,0xe1,0xcb,0x38,0xe2,0xd8,0x36,
|
||||
0xe3,0xe5,0x34,0xef,0xf2,0x58,0xfb,0xff,0x7d,0xfb,0xff,0x7d,
|
||||
0x39,0x17,0x01,0x5e,0x23,0x04,0x83,0x30,0x08,0xa5,0x47,0x16,
|
||||
0xc8,0x5f,0x24,0xe3,0x78,0x20,0xff,0x91,0x1d,0xff,0xab,0x1d,
|
||||
0xff,0xc5,0x1d,0xff,0xce,0x34,0xff,0xd8,0x4c,0xff,0xe6,0x51,
|
||||
0xff,0xf4,0x56,0xff,0xf9,0x77,0xff,0xff,0x98,0xff,0xff,0x98,
|
||||
0x45,0x19,0x04,0x72,0x1e,0x11,0x9f,0x24,0x1e,0xb3,0x3a,0x20,
|
||||
0xc8,0x51,0x22,0xe3,0x69,0x20,0xff,0x81,0x1e,0xff,0x8c,0x25,
|
||||
0xff,0x98,0x2c,0xff,0xae,0x38,0xff,0xc5,0x45,0xff,0xc5,0x59,
|
||||
0xff,0xc6,0x6d,0xff,0xd5,0x87,0xff,0xe4,0xa1,0xff,0xe4,0xa1,
|
||||
0x4a,0x17,0x04,0x7e,0x1a,0x0d,0xb2,0x1d,0x17,0xc8,0x21,0x19,
|
||||
0xdf,0x25,0x1c,0xec,0x3b,0x38,0xfa,0x52,0x55,0xfc,0x61,0x61,
|
||||
0xff,0x70,0x6e,0xff,0x7f,0x7e,0xff,0x8f,0x8f,0xff,0x9d,0x9e,
|
||||
0xff,0xab,0xad,0xff,0xb9,0xbd,0xff,0xc7,0xce,0xff,0xc7,0xce,
|
||||
0x05,0x05,0x68,0x3b,0x13,0x6d,0x71,0x22,0x72,0x8b,0x2a,0x8c,
|
||||
0xa5,0x32,0xa6,0xb9,0x38,0xba,0xcd,0x3e,0xcf,0xdb,0x47,0xdd,
|
||||
0xea,0x51,0xeb,0xf4,0x5f,0xf5,0xfe,0x6d,0xff,0xfe,0x7a,0xfd,
|
||||
0xff,0x87,0xfb,0xff,0x95,0xfd,0xff,0xa4,0xff,0xff,0xa4,0xff,
|
||||
0x28,0x04,0x79,0x40,0x09,0x84,0x59,0x0f,0x90,0x70,0x24,0x9d,
|
||||
0x88,0x39,0xaa,0xa4,0x41,0xc3,0xc0,0x4a,0xdc,0xd0,0x54,0xed,
|
||||
0xe0,0x5e,0xff,0xe9,0x6d,0xff,0xf2,0x7c,0xff,0xf8,0x8a,0xff,
|
||||
0xff,0x98,0xff,0xfe,0xa1,0xff,0xfe,0xab,0xff,0xfe,0xab,0xff,
|
||||
0x35,0x08,0x8a,0x42,0x0a,0xad,0x50,0x0c,0xd0,0x64,0x28,0xd0,
|
||||
0x79,0x45,0xd0,0x8d,0x4b,0xd4,0xa2,0x51,0xd9,0xb0,0x58,0xec,
|
||||
0xbe,0x60,0xff,0xc5,0x6b,0xff,0xcc,0x77,0xff,0xd1,0x83,0xff,
|
||||
0xd7,0x90,0xff,0xdb,0x9d,0xff,0xdf,0xaa,0xff,0xdf,0xaa,0xff,
|
||||
0x05,0x1e,0x81,0x06,0x26,0xa5,0x08,0x2f,0xca,0x26,0x3d,0xd4,
|
||||
0x44,0x4c,0xde,0x4f,0x5a,0xee,0x5a,0x68,0xff,0x65,0x75,0xff,
|
||||
0x71,0x83,0xff,0x80,0x91,0xff,0x90,0xa0,0xff,0x97,0xa9,0xff,
|
||||
0x9f,0xb2,0xff,0xaf,0xbe,0xff,0xc0,0xcb,0xff,0xc0,0xcb,0xff,
|
||||
0x05,0x1e,0x81,0x06,0x26,0xa5,0x08,0x2f,0xca,0x26,0x3d,0xd4,
|
||||
0x44,0x4c,0xde,0x4f,0x5a,0xee,0x5a,0x68,0xff,0x65,0x75,0xff,
|
||||
0x71,0x83,0xff,0x80,0x91,0xff,0x90,0xa0,0xff,0x97,0xa9,0xff,
|
||||
0x9f,0xb2,0xff,0xaf,0xbe,0xff,0xc0,0xcb,0xff,0xc0,0xcb,0xff,
|
||||
0x0c,0x04,0x8b,0x22,0x18,0xa0,0x38,0x2d,0xb5,0x48,0x3e,0xc7,
|
||||
0x58,0x4f,0xda,0x61,0x59,0xec,0x6b,0x64,0xff,0x7a,0x74,0xff,
|
||||
0x8a,0x84,0xff,0x91,0x8e,0xff,0x99,0x98,0xff,0xa5,0xa3,0xff,
|
||||
0xb1,0xae,0xff,0xb8,0xb8,0xff,0xc0,0xc2,0xff,0xc0,0xc2,0xff,
|
||||
0x1d,0x29,0x5a,0x1d,0x38,0x76,0x1d,0x48,0x92,0x1c,0x5c,0xac,
|
||||
0x1c,0x71,0xc6,0x32,0x86,0xcf,0x48,0x9b,0xd9,0x4e,0xa8,0xec,
|
||||
0x55,0xb6,0xff,0x70,0xc7,0xff,0x8c,0xd8,0xff,0x93,0xdb,0xff,
|
||||
0x9b,0xdf,0xff,0xaf,0xe4,0xff,0xc3,0xe9,0xff,0xc3,0xe9,0xff,
|
||||
0x2f,0x43,0x02,0x39,0x52,0x02,0x44,0x61,0x03,0x41,0x7a,0x12,
|
||||
0x3e,0x94,0x21,0x4a,0x9f,0x2e,0x57,0xab,0x3b,0x5c,0xbd,0x55,
|
||||
0x61,0xd0,0x70,0x69,0xe2,0x7a,0x72,0xf5,0x84,0x7c,0xfa,0x8d,
|
||||
0x87,0xff,0x97,0x9a,0xff,0xa6,0xad,0xff,0xb6,0xad,0xff,0xb6,
|
||||
0x0a,0x41,0x08,0x0d,0x54,0x0a,0x10,0x68,0x0d,0x13,0x7d,0x0f,
|
||||
0x16,0x92,0x12,0x19,0xa5,0x14,0x1c,0xb9,0x17,0x1e,0xc9,0x19,
|
||||
0x21,0xd9,0x1b,0x47,0xe4,0x2d,0x6e,0xf0,0x40,0x78,0xf7,0x4d,
|
||||
0x83,0xff,0x5b,0x9a,0xff,0x7a,0xb2,0xff,0x9a,0xb2,0xff,0x9a,
|
||||
0x04,0x41,0x0b,0x05,0x53,0x0e,0x06,0x66,0x11,0x07,0x77,0x14,
|
||||
0x08,0x88,0x17,0x09,0x9b,0x1a,0x0b,0xaf,0x1d,0x48,0xc4,0x1f,
|
||||
0x86,0xd9,0x22,0x8f,0xe9,0x24,0x99,0xf9,0x27,0xa8,0xfc,0x41,
|
||||
0xb7,0xff,0x5b,0xc9,0xff,0x6e,0xdc,0xff,0x81,0xdc,0xff,0x81,
|
||||
0x02,0x35,0x0f,0x07,0x3f,0x15,0x0c,0x4a,0x1c,0x2d,0x5f,0x1e,
|
||||
0x4f,0x74,0x20,0x59,0x83,0x24,0x64,0x92,0x28,0x82,0xa1,0x2e,
|
||||
0xa1,0xb0,0x34,0xa9,0xc1,0x3a,0xb2,0xd2,0x41,0xc4,0xd9,0x45,
|
||||
0xd6,0xe1,0x49,0xe4,0xf0,0x4e,0xf2,0xff,0x53,0xf2,0xff,0x53,
|
||||
const byte REGION_PALETTE_NTSC_CRT_WARM[ ] = {
|
||||
0x00, 0x00, 0x00, 0x0d, 0x0d, 0x0d, 0x28, 0x28, 0x28, 0x3e, 0x3e, 0x3e,
|
||||
0x52, 0x52, 0x52, 0x65, 0x65, 0x65, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88,
|
||||
0x98, 0x98, 0x98, 0xa8, 0xa8, 0xa8, 0xb7, 0xb7, 0xb7, 0xc6, 0xc6, 0xc6,
|
||||
0xd5, 0xd5, 0xd5, 0xe3, 0xe3, 0xe3, 0xf1, 0xf1, 0xf1, 0xff, 0xff, 0xff,
|
||||
0x42, 0x28, 0x00, 0x54, 0x3d, 0x00, 0x65, 0x4f, 0x00, 0x75, 0x60, 0x00,
|
||||
0x84, 0x70, 0x00, 0x93, 0x80, 0x00, 0xa2, 0x8f, 0x00, 0xb0, 0x9d, 0x00,
|
||||
0xbe, 0xac, 0x00, 0xcb, 0xb9, 0x00, 0xd8, 0xc7, 0x00, 0xe5, 0xd4, 0x1a,
|
||||
0xf2, 0xe1, 0x30, 0xfe, 0xee, 0x43, 0xff, 0xfb, 0x55, 0xff, 0xff, 0x66,
|
||||
0x6d, 0x0e, 0x00, 0x7d, 0x27, 0x00, 0x8c, 0x3b, 0x00, 0x9a, 0x4e, 0x00,
|
||||
0xa9, 0x5f, 0x00, 0xb7, 0x6f, 0x00, 0xc4, 0x7f, 0x00, 0xd1, 0x8e, 0x00,
|
||||
0xde, 0x9c, 0x02, 0xeb, 0xab, 0x1f, 0xf8, 0xb8, 0x35, 0xff, 0xc6, 0x48,
|
||||
0xff, 0xd3, 0x59, 0xff, 0xe0, 0x6a, 0xff, 0xed, 0x7a, 0xff, 0xfa, 0x89,
|
||||
0x85, 0x00, 0x00, 0x94, 0x0f, 0x00, 0xa2, 0x27, 0x00, 0xb0, 0x3b, 0x00,
|
||||
0xbe, 0x4e, 0x06, 0xcb, 0x5f, 0x21, 0xd8, 0x6f, 0x37, 0xe5, 0x7f, 0x49,
|
||||
0xf2, 0x8e, 0x5b, 0xff, 0x9d, 0x6b, 0xff, 0xab, 0x7b, 0xff, 0xb9, 0x8a,
|
||||
0xff, 0xc6, 0x99, 0xff, 0xd3, 0xa7, 0xff, 0xe1, 0xb5, 0xff, 0xed, 0xc3,
|
||||
0x89, 0x00, 0x24, 0x98, 0x00, 0x38, 0xa6, 0x17, 0x4b, 0xb4, 0x2e, 0x5c,
|
||||
0xc1, 0x42, 0x6d, 0xcf, 0x53, 0x7d, 0xdc, 0x64, 0x8c, 0xe9, 0x74, 0x9a,
|
||||
0xf5, 0x84, 0xa9, 0xff, 0x93, 0xb6, 0xff, 0xa1, 0xc4, 0xff, 0xaf, 0xd1,
|
||||
0xff, 0xbd, 0xde, 0xff, 0xca, 0xeb, 0xff, 0xd8, 0xf8, 0xff, 0xe5, 0xff,
|
||||
0x78, 0x00, 0x7d, 0x88, 0x00, 0x8c, 0x96, 0x11, 0x9a, 0xa5, 0x29, 0xa9,
|
||||
0xb3, 0x3d, 0xb6, 0xc0, 0x4f, 0xc4, 0xce, 0x60, 0xd1, 0xdb, 0x71, 0xde,
|
||||
0xe8, 0x80, 0xeb, 0xf5, 0x8f, 0xf8, 0xff, 0x9e, 0xff, 0xff, 0xac, 0xff,
|
||||
0xff, 0xba, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xd5, 0xff, 0xff, 0xe2, 0xff,
|
||||
0x55, 0x00, 0xb4, 0x66, 0x00, 0xc2, 0x76, 0x18, 0xcf, 0x85, 0x2e, 0xdc,
|
||||
0x94, 0x42, 0xe9, 0xa2, 0x54, 0xf6, 0xb0, 0x65, 0xff, 0xbe, 0x75, 0xff,
|
||||
0xcc, 0x84, 0xff, 0xd9, 0x93, 0xff, 0xe6, 0xa2, 0xff, 0xf2, 0xb0, 0xff,
|
||||
0xff, 0xbd, 0xff, 0xff, 0xcb, 0xff, 0xff, 0xd8, 0xff, 0xff, 0xe5, 0xff,
|
||||
0x1e, 0x00, 0xcd, 0x33, 0x10, 0xdb, 0x46, 0x28, 0xe7, 0x58, 0x3c, 0xf4,
|
||||
0x69, 0x4f, 0xff, 0x79, 0x60, 0xff, 0x88, 0x70, 0xff, 0x97, 0x80, 0xff,
|
||||
0xa5, 0x8f, 0xff, 0xb3, 0x9d, 0xff, 0xc1, 0xac, 0xff, 0xce, 0xb9, 0xff,
|
||||
0xdb, 0xc7, 0xff, 0xe8, 0xd4, 0xff, 0xf5, 0xe1, 0xff, 0xff, 0xee, 0xff,
|
||||
0x00, 0x10, 0xc6, 0x00, 0x28, 0xd4, 0x06, 0x3c, 0xe1, 0x21, 0x4f, 0xee,
|
||||
0x36, 0x60, 0xfa, 0x49, 0x70, 0xff, 0x5b, 0x80, 0xff, 0x6b, 0x8f, 0xff,
|
||||
0x7b, 0x9d, 0xff, 0x8a, 0xab, 0xff, 0x99, 0xb9, 0xff, 0xa7, 0xc7, 0xff,
|
||||
0xb5, 0xd4, 0xff, 0xc3, 0xe1, 0xff, 0xd0, 0xee, 0xff, 0xdd, 0xfa, 0xff,
|
||||
0x00, 0x2a, 0xa0, 0x00, 0x3e, 0xae, 0x00, 0x50, 0xbc, 0x00, 0x61, 0xc9,
|
||||
0x00, 0x71, 0xd7, 0x1b, 0x81, 0xe3, 0x31, 0x90, 0xf0, 0x44, 0x9e, 0xfd,
|
||||
0x56, 0xac, 0xff, 0x67, 0xba, 0xff, 0x77, 0xc8, 0xff, 0x86, 0xd5, 0xff,
|
||||
0x95, 0xe2, 0xff, 0xa3, 0xef, 0xff, 0xb1, 0xfb, 0xff, 0xbf, 0xff, 0xff,
|
||||
0x00, 0x3c, 0x5b, 0x00, 0x4f, 0x6c, 0x00, 0x60, 0x7b, 0x00, 0x70, 0x8b,
|
||||
0x00, 0x80, 0x99, 0x00, 0x8f, 0xa8, 0x15, 0x9d, 0xb6, 0x2c, 0xab, 0xc3,
|
||||
0x40, 0xb9, 0xd0, 0x52, 0xc7, 0xde, 0x63, 0xd4, 0xea, 0x73, 0xe1, 0xf7,
|
||||
0x83, 0xee, 0xff, 0x92, 0xfa, 0xff, 0xa0, 0xff, 0xff, 0xae, 0xff, 0xff,
|
||||
0x00, 0x47, 0x00, 0x00, 0x59, 0x00, 0x00, 0x69, 0x1e, 0x00, 0x79, 0x33,
|
||||
0x00, 0x88, 0x47, 0x00, 0x97, 0x58, 0x18, 0xa5, 0x69, 0x2e, 0xb3, 0x79,
|
||||
0x42, 0xc1, 0x88, 0x54, 0xce, 0x97, 0x65, 0xdb, 0xa5, 0x75, 0xe8, 0xb3,
|
||||
0x84, 0xf5, 0xc1, 0x93, 0xff, 0xce, 0xa1, 0xff, 0xdb, 0xaf, 0xff, 0xe8,
|
||||
0x00, 0x49, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x7b, 0x00,
|
||||
0x06, 0x8a, 0x00, 0x21, 0x99, 0x00, 0x36, 0xa7, 0x08, 0x49, 0xb5, 0x23,
|
||||
0x5b, 0xc2, 0x38, 0x6b, 0xd0, 0x4a, 0x7b, 0xdd, 0x5c, 0x8a, 0xea, 0x6c,
|
||||
0x99, 0xf6, 0x7c, 0xa7, 0xff, 0x8b, 0xb5, 0xff, 0x9a, 0xc3, 0xff, 0xa8,
|
||||
0x00, 0x42, 0x00, 0x00, 0x54, 0x00, 0x12, 0x64, 0x00, 0x2a, 0x75, 0x00,
|
||||
0x3e, 0x84, 0x00, 0x50, 0x93, 0x00, 0x61, 0xa1, 0x00, 0x71, 0xaf, 0x00,
|
||||
0x81, 0xbd, 0x00, 0x90, 0xcb, 0x00, 0x9f, 0xd8, 0x1a, 0xad, 0xe5, 0x30,
|
||||
0xba, 0xf1, 0x43, 0xc8, 0xfe, 0x55, 0xd5, 0xff, 0x66, 0xe2, 0xff, 0x76,
|
||||
0x27, 0x32, 0x00, 0x3c, 0x45, 0x00, 0x4e, 0x57, 0x00, 0x5f, 0x68, 0x00,
|
||||
0x70, 0x78, 0x00, 0x7f, 0x87, 0x00, 0x8e, 0x96, 0x00, 0x9d, 0xa4, 0x00,
|
||||
0xab, 0xb2, 0x00, 0xb9, 0xc0, 0x00, 0xc6, 0xcd, 0x00, 0xd4, 0xda, 0x14,
|
||||
0xe1, 0xe7, 0x2b, 0xee, 0xf4, 0x3f, 0xfa, 0xff, 0x51, 0xff, 0xff, 0x62,
|
||||
0x5b, 0x1b, 0x00, 0x6c, 0x31, 0x00, 0x7b, 0x45, 0x00, 0x8b, 0x56, 0x00,
|
||||
0x99, 0x67, 0x00, 0xa8, 0x77, 0x00, 0xb6, 0x86, 0x00, 0xc3, 0x95, 0x00,
|
||||
0xd0, 0xa4, 0x00, 0xde, 0xb2, 0x00, 0xea, 0xbf, 0x18, 0xf7, 0xcd, 0x2e,
|
||||
0xff, 0xda, 0x42, 0xff, 0xe7, 0x54, 0xff, 0xf3, 0x65, 0xff, 0xff, 0x75
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
extern uint sound_lenght;
|
||||
extern uint video_height;
|
||||
const byte REGION_PALETTE_NTSC_CRT_HOT[ ] = {
|
||||
0x00, 0x00, 0x00, 0x0d, 0x0d, 0x0d, 0x28, 0x28, 0x28, 0x3e, 0x3e, 0x3e,
|
||||
0x52, 0x52, 0x52, 0x65, 0x65, 0x65, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88,
|
||||
0x98, 0x98, 0x98, 0xa8, 0xa8, 0xa8, 0xb7, 0xb7, 0xb7, 0xc6, 0xc6, 0xc6,
|
||||
0xd5, 0xd5, 0xd5, 0xe3, 0xe3, 0xe3, 0xf1, 0xf1, 0xf1, 0xff, 0xff, 0xff,
|
||||
0x42, 0x28, 0x00, 0x54, 0x3d, 0x00, 0x65, 0x4f, 0x00, 0x75, 0x60, 0x00,
|
||||
0x84, 0x70, 0x00, 0x93, 0x80, 0x00, 0xa2, 0x8f, 0x00, 0xb0, 0x9d, 0x00,
|
||||
0xbe, 0xac, 0x00, 0xcb, 0xb9, 0x00, 0xd8, 0xc7, 0x00, 0xe5, 0xd4, 0x1a,
|
||||
0xf2, 0xe1, 0x30, 0xfe, 0xee, 0x43, 0xff, 0xfb, 0x55, 0xff, 0xff, 0x66,
|
||||
0x6e, 0x0d, 0x00, 0x7e, 0x26, 0x00, 0x8d, 0x3a, 0x00, 0x9b, 0x4d, 0x00,
|
||||
0xaa, 0x5e, 0x00, 0xb8, 0x6f, 0x00, 0xc5, 0x7e, 0x00, 0xd2, 0x8d, 0x00,
|
||||
0xdf, 0x9c, 0x07, 0xec, 0xaa, 0x22, 0xf9, 0xb8, 0x37, 0xff, 0xc6, 0x4a,
|
||||
0xff, 0xd3, 0x5b, 0xff, 0xe0, 0x6c, 0xff, 0xed, 0x7b, 0xff, 0xf9, 0x8b,
|
||||
0x86, 0x00, 0x00, 0x95, 0x0d, 0x00, 0xa3, 0x26, 0x00, 0xb1, 0x3a, 0x00,
|
||||
0xbf, 0x4d, 0x11, 0xcc, 0x5e, 0x29, 0xd9, 0x6e, 0x3d, 0xe6, 0x7e, 0x4f,
|
||||
0xf3, 0x8d, 0x60, 0xff, 0x9c, 0x71, 0xff, 0xaa, 0x80, 0xff, 0xb8, 0x8f,
|
||||
0xff, 0xc5, 0x9e, 0xff, 0xd3, 0xac, 0xff, 0xe0, 0xba, 0xff, 0xed, 0xc7,
|
||||
0x88, 0x00, 0x2f, 0x97, 0x00, 0x43, 0xa5, 0x16, 0x55, 0xb3, 0x2d, 0x65,
|
||||
0xc1, 0x41, 0x75, 0xce, 0x53, 0x85, 0xdb, 0x64, 0x94, 0xe8, 0x74, 0xa2,
|
||||
0xf5, 0x83, 0xb0, 0xff, 0x92, 0xbe, 0xff, 0xa1, 0xcb, 0xff, 0xaf, 0xd9,
|
||||
0xff, 0xbc, 0xe5, 0xff, 0xca, 0xf2, 0xff, 0xd7, 0xff, 0xff, 0xe4, 0xff,
|
||||
0x75, 0x00, 0x86, 0x84, 0x00, 0x95, 0x93, 0x11, 0xa3, 0xa1, 0x29, 0xb1,
|
||||
0xaf, 0x3d, 0xbf, 0xbd, 0x4f, 0xcc, 0xcb, 0x61, 0xda, 0xd8, 0x71, 0xe7,
|
||||
0xe5, 0x80, 0xf3, 0xf1, 0x8f, 0xff, 0xfe, 0x9e, 0xff, 0xff, 0xac, 0xff,
|
||||
0xff, 0xba, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xd5, 0xff, 0xff, 0xe2, 0xff,
|
||||
0x4d, 0x00, 0xbb, 0x5e, 0x00, 0xc8, 0x6e, 0x1a, 0xd6, 0x7e, 0x30, 0xe3,
|
||||
0x8d, 0x44, 0xef, 0x9c, 0x56, 0xfc, 0xaa, 0x66, 0xff, 0xb8, 0x76, 0xff,
|
||||
0xc5, 0x86, 0xff, 0xd3, 0x95, 0xff, 0xe0, 0xa3, 0xff, 0xed, 0xb1, 0xff,
|
||||
0xf9, 0xbf, 0xff, 0xff, 0xcc, 0xff, 0xff, 0xd9, 0xff, 0xff, 0xe6, 0xff,
|
||||
0x0e, 0x00, 0xcf, 0x26, 0x15, 0xdc, 0x3b, 0x2c, 0xe9, 0x4d, 0x40, 0xf5,
|
||||
0x5f, 0x52, 0xff, 0x6f, 0x63, 0xff, 0x7f, 0x73, 0xff, 0x8e, 0x83, 0xff,
|
||||
0x9c, 0x92, 0xff, 0xaa, 0xa0, 0xff, 0xb8, 0xae, 0xff, 0xc6, 0xbc, 0xff,
|
||||
0xd3, 0xc9, 0xff, 0xe0, 0xd7, 0xff, 0xed, 0xe4, 0xff, 0xfa, 0xf0, 0xff,
|
||||
0x00, 0x17, 0xc0, 0x00, 0x2e, 0xcd, 0x00, 0x41, 0xda, 0x11, 0x53, 0xe7,
|
||||
0x29, 0x64, 0xf4, 0x3d, 0x74, 0xff, 0x50, 0x84, 0xff, 0x61, 0x93, 0xff,
|
||||
0x71, 0xa1, 0xff, 0x81, 0xaf, 0xff, 0x90, 0xbd, 0xff, 0x9e, 0xca, 0xff,
|
||||
0xac, 0xd8, 0xff, 0xba, 0xe4, 0xff, 0xc8, 0xf1, 0xff, 0xd5, 0xfe, 0xff,
|
||||
0x00, 0x30, 0x90, 0x00, 0x43, 0x9e, 0x00, 0x55, 0xac, 0x00, 0x66, 0xba,
|
||||
0x00, 0x76, 0xc8, 0x0e, 0x85, 0xd5, 0x27, 0x94, 0xe2, 0x3b, 0xa2, 0xef,
|
||||
0x4e, 0xb0, 0xfb, 0x5f, 0xbe, 0xff, 0x6f, 0xcc, 0xff, 0x7f, 0xd9, 0xff,
|
||||
0x8e, 0xe6, 0xff, 0x9d, 0xf2, 0xff, 0xab, 0xff, 0xff, 0xb9, 0xff, 0xff,
|
||||
0x00, 0x40, 0x3f, 0x00, 0x53, 0x51, 0x00, 0x63, 0x62, 0x00, 0x74, 0x72,
|
||||
0x00, 0x83, 0x82, 0x00, 0x92, 0x91, 0x12, 0xa0, 0x9f, 0x2a, 0xaf, 0xad,
|
||||
0x3e, 0xbc, 0xbb, 0x50, 0xca, 0xc8, 0x61, 0xd7, 0xd6, 0x71, 0xe4, 0xe3,
|
||||
0x81, 0xf1, 0xef, 0x90, 0xfd, 0xfc, 0x9e, 0xff, 0xff, 0xac, 0xff, 0xff,
|
||||
0x00, 0x49, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x7a, 0x09,
|
||||
0x00, 0x8a, 0x23, 0x04, 0x98, 0x38, 0x20, 0xa7, 0x4b, 0x35, 0xb5, 0x5c,
|
||||
0x48, 0xc2, 0x6c, 0x5a, 0xd0, 0x7c, 0x6a, 0xdd, 0x8b, 0x7a, 0xea, 0x9a,
|
||||
0x89, 0xf6, 0xa8, 0x98, 0xff, 0xb6, 0xa6, 0xff, 0xc4, 0xb4, 0xff, 0xd1,
|
||||
0x00, 0x47, 0x00, 0x00, 0x59, 0x00, 0x00, 0x69, 0x00, 0x00, 0x79, 0x00,
|
||||
0x1d, 0x88, 0x00, 0x33, 0x97, 0x00, 0x46, 0xa5, 0x00, 0x58, 0xb3, 0x00,
|
||||
0x68, 0xc1, 0x16, 0x78, 0xce, 0x2d, 0x87, 0xdc, 0x41, 0x96, 0xe8, 0x53,
|
||||
0xa5, 0xf5, 0x64, 0xb3, 0xff, 0x74, 0xc0, 0xff, 0x83, 0xce, 0xff, 0x92,
|
||||
0x00, 0x3c, 0x00, 0x17, 0x4e, 0x00, 0x2e, 0x60, 0x00, 0x41, 0x70, 0x00,
|
||||
0x53, 0x7f, 0x00, 0x64, 0x8f, 0x00, 0x74, 0x9d, 0x00, 0x84, 0xab, 0x00,
|
||||
0x93, 0xb9, 0x00, 0xa1, 0xc7, 0x00, 0xaf, 0xd4, 0x00, 0xbd, 0xe1, 0x1e,
|
||||
0xca, 0xee, 0x34, 0xd8, 0xfa, 0x47, 0xe5, 0xff, 0x59, 0xf1, 0xff, 0x69,
|
||||
0x42, 0x29, 0x00, 0x54, 0x3d, 0x00, 0x64, 0x4f, 0x00, 0x74, 0x60, 0x00,
|
||||
0x84, 0x71, 0x00, 0x93, 0x80, 0x00, 0xa1, 0x8f, 0x00, 0xaf, 0x9e, 0x00,
|
||||
0xbd, 0xac, 0x00, 0xca, 0xba, 0x00, 0xd8, 0xc7, 0x00, 0xe5, 0xd4, 0x1a,
|
||||
0xf1, 0xe1, 0x30, 0xfe, 0xee, 0x43, 0xff, 0xfb, 0x55, 0xff, 0xff, 0x66,
|
||||
0x6e, 0x0d, 0x00, 0x7d, 0x26, 0x00, 0x8c, 0x3b, 0x00, 0x9b, 0x4d, 0x00,
|
||||
0xa9, 0x5e, 0x00, 0xb7, 0x6f, 0x00, 0xc5, 0x7e, 0x00, 0xd2, 0x8d, 0x00,
|
||||
0xdf, 0x9c, 0x05, 0xec, 0xaa, 0x21, 0xf9, 0xb8, 0x36, 0xff, 0xc6, 0x49,
|
||||
0xff, 0xd3, 0x5a, 0xff, 0xe0, 0x6b, 0xff, 0xed, 0x7b, 0xff, 0xf9, 0x8a
|
||||
};
|
||||
|
||||
void region_Reset( ) {
|
||||
if(region_type == REGION_PAL || (region_type == REGION_AUTO && cartridge_region == REGION_PAL)) {
|
||||
maria_displayArea = REGION_DISPLAY_AREA_PAL;
|
||||
maria_visibleArea = REGION_VISIBLE_AREA_PAL;
|
||||
if(palette_default)
|
||||
palette_Load(REGION_PALETTE_PAL); // Added check for default - bberlin
|
||||
prosystem_frequency = REGION_FREQUENCY_PAL;
|
||||
prosystem_scanlines = REGION_SCANLINES_PAL;
|
||||
pokey_size = 624;
|
||||
}
|
||||
else {
|
||||
maria_displayArea = REGION_DISPLAY_AREA_NTSC;
|
||||
maria_visibleArea = REGION_VISIBLE_AREA_NTSC;
|
||||
if(palette_default)
|
||||
palette_Load(REGION_PALETTE_NTSC); // Added check for default - bberlin
|
||||
prosystem_frequency = REGION_FREQUENCY_NTSC;
|
||||
prosystem_scanlines = REGION_SCANLINES_NTSC;
|
||||
pokey_size = 524;
|
||||
}
|
||||
maria_displayArea.GetLength = (maria_displayArea.right - maria_displayArea.left) + 1;
|
||||
maria_displayArea.GetHeight = (maria_displayArea.bottom - maria_displayArea.top) + 1;
|
||||
maria_displayArea.GetArea = maria_displayArea.GetLength * maria_displayArea.GetHeight;
|
||||
|
||||
maria_visibleArea.GetLength = (maria_visibleArea.right - maria_visibleArea.left) + 1;
|
||||
maria_visibleArea.GetHeight = (maria_visibleArea.bottom - maria_visibleArea.top) + 1;
|
||||
maria_visibleArea.GetArea = maria_visibleArea.GetLength * maria_visibleArea.GetHeight;
|
||||
|
||||
video_height = maria_visibleArea.bottom-maria_displayArea.top;
|
||||
// ---------------------------------
|
||||
// We only support NTSC for A7800DS
|
||||
// ---------------------------------
|
||||
void region_Reset( )
|
||||
{
|
||||
if(myCartInfo.palette == 0) palette_Load(REGION_PALETTE_NTSC_CRT_COOL);
|
||||
if(myCartInfo.palette == 1) palette_Load(REGION_PALETTE_NTSC_CRT_WARM);
|
||||
if(myCartInfo.palette == 2) palette_Load(REGION_PALETTE_NTSC_CRT_HOT);
|
||||
}
|
||||
|
|
|
@ -24,23 +24,23 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#include "Riot.h"
|
||||
|
||||
bool riot_timing __attribute__((section(".dtcm"))) = false;
|
||||
word riot_timer __attribute__((section(".dtcm"))) = TIM64T;
|
||||
byte 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;
|
||||
|
||||
bool riot_elapsed __attribute__((section(".dtcm")));
|
||||
int riot_currentTime __attribute__((section(".dtcm")));
|
||||
word riot_clocks __attribute__((section(".dtcm")));
|
||||
word 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);
|
||||
riot_SetDRB(0);
|
||||
|
||||
riot_timing = false;
|
||||
riot_and_wsync = 0;
|
||||
riot_timer = TIM64T;
|
||||
riot_intervals = 0;
|
||||
riot_clocks = 0;
|
||||
|
@ -73,13 +73,13 @@ void riot_Reset(void) {
|
|||
// | 15 | Console | Left Difficulty
|
||||
// | 16 | Console | Right Difficulty
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
void riot_SetInput(const byte* input) {
|
||||
ITCM_CODE void riot_SetInput(const byte* input) {
|
||||
/*gdement: Comments are messy, but wanted to document how this all works.
|
||||
Changed this routine to support 1 vs 2 button modes.
|
||||
Also added the interaction of CTLSWA and DRA on the SWCHA output, and same for SWCHB.
|
||||
SWCHA is directionals. SWCHB is console switches and button mode.
|
||||
button signals are in high bits of INPT0-5.*/
|
||||
|
||||
|
||||
memory_ram[SWCHA] = ((~memory_ram[CTLSWA]) | riot_dra); /*SWCHA as driven by RIOT*/
|
||||
|
||||
/*now console switches will force bits to ground:*/
|
||||
|
@ -194,55 +194,6 @@ void riot_SetInput(const byte* input) {
|
|||
memory_ram[INPT2] &= 0x7f;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (input[0x00] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x80; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x80 ;
|
||||
if (input[0x01] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x40; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x40;
|
||||
if (input[0x02] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x20; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x20;
|
||||
if (input[0x03] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x10; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x10;
|
||||
|
||||
|
||||
if(input[0x04]) {
|
||||
memory_ram[INPT0] = memory_ram[INPT0] | 0x80;
|
||||
memory_ram[INPT4] = memory_ram[INPT4] &~ 0x80;
|
||||
}
|
||||
else {
|
||||
memory_ram[INPT0] = memory_ram[INPT0] &~ 0x80;
|
||||
memory_ram[INPT4] = memory_ram[INPT4] | 0x80;
|
||||
}
|
||||
if(input[0x05]) {
|
||||
memory_ram[INPT1] = memory_ram[INPT1] | 0x80;
|
||||
memory_ram[INPT4] = memory_ram[INPT4] &~ 0x80;
|
||||
}
|
||||
else {
|
||||
memory_ram[INPT1] = memory_ram[INPT1] &~ 0x80;
|
||||
memory_ram[INPT4] = memory_ram[INPT4] | 0x80;
|
||||
}
|
||||
if (input[0x06] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x08; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x08;
|
||||
if (input[0x07] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x04; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x04;
|
||||
if (input[0x08] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x02; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x02;
|
||||
if (input[0x09] ) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x01; else memory_ram[SWCHA] = memory_ram[SWCHA] | 0x01;
|
||||
if(input[0x0a]) {
|
||||
memory_ram[INPT2] = memory_ram[INPT2] | 0x80;
|
||||
memory_ram[INPT5] = memory_ram[INPT5] &~ 0x80;
|
||||
}
|
||||
else {
|
||||
memory_ram[INPT2] = memory_ram[INPT2] &~ 0x80;
|
||||
memory_ram[INPT5] = memory_ram[INPT5] | 0x80;
|
||||
}
|
||||
if(input[0x0b]) {
|
||||
memory_ram[INPT3] = memory_ram[INPT3] | 0x80;
|
||||
memory_ram[INPT5] = memory_ram[INPT5] &~ 0x80;
|
||||
}
|
||||
else {
|
||||
memory_ram[INPT3] = memory_ram[INPT3] &~ 0x80;
|
||||
memory_ram[INPT5] = memory_ram[INPT5] | 0x80;
|
||||
}
|
||||
if (input[0x0c]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x01; else memory_ram[SWCHB] = memory_ram[SWCHB] | 0x01;
|
||||
if (input[0x0d]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x02; else memory_ram[SWCHB] = memory_ram[SWCHB] | 0x02;
|
||||
if (input[0x0e]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x08; else memory_ram[SWCHB] = memory_ram[SWCHB] | 0x08;
|
||||
if (input[0x0f]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x40; else memory_ram[SWCHB] = memory_ram[SWCHB] | 0x40;
|
||||
if (input[0x10]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x80; else memory_ram[SWCHB] = memory_ram[SWCHB] | 0x80;
|
||||
*/
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
|
@ -274,25 +225,25 @@ void riot_SetTimer(word timer, byte intervals)
|
|||
case T1024T:
|
||||
riot_clocks = 1024;
|
||||
riot_shift = 10;
|
||||
riot_timing = true;
|
||||
riot_and_wsync |= 2;
|
||||
break;
|
||||
case TIM1T:
|
||||
riot_clocks = 1;
|
||||
riot_shift = 0;
|
||||
riot_timing = true;
|
||||
riot_and_wsync |= 2;
|
||||
break;
|
||||
case TIM8T:
|
||||
riot_clocks = 8;
|
||||
riot_shift = 3;
|
||||
riot_timing = true;
|
||||
riot_and_wsync |= 2;
|
||||
break;
|
||||
case TIM64T:
|
||||
riot_clocks = 64;
|
||||
riot_shift = 6;
|
||||
riot_timing = true;
|
||||
riot_and_wsync |= 2;
|
||||
break;
|
||||
}
|
||||
if(riot_timing) {
|
||||
if(riot_and_wsync) {
|
||||
riot_currentTime = riot_clocks * intervals;
|
||||
riot_elapsed = false;
|
||||
}
|
||||
|
@ -301,7 +252,7 @@ void riot_SetTimer(word timer, byte intervals)
|
|||
// ----------------------------------------------------------------------------
|
||||
// UpdateTimer
|
||||
// ----------------------------------------------------------------------------
|
||||
void inline riot_UpdateTimer(byte cycles)
|
||||
ITCM_CODE void inline riot_UpdateTimer(byte cycles)
|
||||
{
|
||||
riot_currentTime -= cycles;
|
||||
if(!riot_elapsed && riot_currentTime > 0)
|
||||
|
@ -319,7 +270,7 @@ void inline riot_UpdateTimer(byte cycles)
|
|||
else
|
||||
{
|
||||
memory_ram[INTIM] = 0;
|
||||
riot_timing = false;
|
||||
riot_and_wsync &= 0xFD;
|
||||
}
|
||||
}
|
||||
else
|
|
@ -37,9 +37,10 @@ extern void riot_SetDRA(byte data);
|
|||
extern void riot_SetDRB(byte data);
|
||||
extern void riot_SetTimer(word timer, byte intervals);
|
||||
extern void riot_UpdateTimer(byte cycles);
|
||||
extern bool riot_timing;
|
||||
extern word riot_timer;
|
||||
extern byte riot_intervals;
|
||||
extern uint riot_and_wsync;
|
||||
extern int riot_timer;
|
||||
extern int riot_intervals;
|
||||
extern u32 snes_adaptor;
|
||||
extern void riot_SetDRA(byte data);
|
||||
extern void riot_SetDRB(byte data);
|
||||
|
||||
|
|
|
@ -28,13 +28,14 @@
|
|||
byte sally_a __attribute__((section(".dtcm"))) = 0;
|
||||
byte sally_x __attribute__((section(".dtcm"))) = 0;
|
||||
byte sally_y __attribute__((section(".dtcm"))) = 0;
|
||||
byte sally_p __attribute__((section(".dtcm"))) = 0;
|
||||
byte sally_s __attribute__((section(".dtcm"))) = 0;
|
||||
pair sally_pc __attribute__((section(".dtcm"))) = {0};
|
||||
uint sally_p __attribute__((section(".dtcm"))) = 0;
|
||||
uint sally_s __attribute__((section(".dtcm"))) = 0;
|
||||
|
||||
static byte sally_opcode __attribute__((section(".dtcm")));
|
||||
static pair sally_address __attribute__((section(".dtcm")));
|
||||
static uint sally_cyclesX4 __attribute__((section(".dtcm")));
|
||||
static PCUnion sally_pc __attribute__((section(".dtcm"))) = {0};
|
||||
static PCUnion sally_address __attribute__((section(".dtcm")));
|
||||
static uint sally_cyclesX4 __attribute__((section(".dtcm")));
|
||||
|
||||
byte last_illegal_opcode = 0;
|
||||
|
||||
#define _fC 0x01
|
||||
#define _fZ 0x02
|
||||
|
@ -54,46 +55,37 @@ static const Vector SALLY_RES = {65533, 65532};
|
|||
static const Vector SALLY_NMI = {65531, 65530};
|
||||
static const Vector SALLY_IRQ = {65535, 65534};
|
||||
|
||||
static byte SALLY_CYCLESX4[256] __attribute__((section(".dtcm"))) =
|
||||
// Cycle table assumes jump is taken - the Sally_Branch() handler will back off 4 cycles if needed
|
||||
static uint SALLY_CYCLESX4[256] __attribute__((section(".dtcm"))) =
|
||||
{
|
||||
7*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,0*4,4*4,6*4,0*4,
|
||||
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
|
||||
6*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,4*4,2*4,2*4,2*4,4*4,4*4,6*4,0*4,
|
||||
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
|
||||
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,3*4,4*4,6*4,0*4,
|
||||
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
|
||||
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,4*4,2*4,2*4,0*4,5*4,4*4,6*4,0*4,
|
||||
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
|
||||
0*4,6*4,0*4,0*4,3*4,3*4,3*4,0*4,2*4,0*4,2*4,0*4,4*4,4*4,4*4,0*4,
|
||||
2*4,6*4,0*4,0*4,4*4,4*4,4*4,0*4,2*4,5*4,2*4,0*4,0*4,5*4,0*4,0*4,
|
||||
2*4,6*4,2*4,0*4,3*4,3*4,3*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,4*4,0*4,
|
||||
2*4,5*4,0*4,0*4,4*4,4*4,4*4,0*4,2*4,4*4,2*4,0*4,4*4,4*4,4*4,0*4,
|
||||
2*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,0*4,
|
||||
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4,
|
||||
2*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,0*4,
|
||||
2*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4
|
||||
7*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,0*4,4*4,6*4,0*4, //00
|
||||
3*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //10
|
||||
6*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,4*4,2*4,2*4,2*4,4*4,4*4,6*4,0*4, //20
|
||||
3*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //30
|
||||
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,3*4,2*4,2*4,2*4,3*4,4*4,6*4,0*4, //40
|
||||
3*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //50
|
||||
6*4,6*4,0*4,0*4,0*4,3*4,5*4,0*4,4*4,2*4,2*4,0*4,5*4,4*4,6*4,0*4, //60
|
||||
3*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4, //70
|
||||
0*4,6*4,0*4,6*4,3*4,3*4,3*4,3*4,2*4,0*4,2*4,0*4,4*4,4*4,4*4,4*4, //80
|
||||
3*4,6*4,0*4,0*4,4*4,4*4,4*4,4*4,2*4,5*4,2*4,0*4,0*4,5*4,0*4,0*4, //90
|
||||
2*4,6*4,2*4,6*4,3*4,3*4,3*4,3*4,2*4,2*4,2*4,0*4,4*4,4*4,4*4,4*4, //A0
|
||||
3*4,5*4,0*4,5*4,4*4,4*4,4*4,4*4,2*4,4*4,2*4,0*4,4*4,4*4,4*4,4*4, //B0
|
||||
2*4,6*4,0*4,8*4,3*4,3*4,5*4,5*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,6*4, //C0
|
||||
3*4,5*4,0*4,8*4,0*4,4*4,6*4,6*4,2*4,4*4,0*4,7*4,0*4,4*4,7*4,7*4, //D0
|
||||
2*4,6*4,0*4,0*4,3*4,3*4,5*4,0*4,2*4,2*4,2*4,0*4,4*4,4*4,6*4,0*4, //E0
|
||||
3*4,5*4,0*4,0*4,0*4,4*4,6*4,0*4,2*4,4*4,0*4,0*4,0*4,4*4,7*4,0*4 //F0
|
||||
};
|
||||
|
||||
#ifdef DS_LITE
|
||||
inline byte memory_Read(word address)
|
||||
{
|
||||
return memory_ram[address];
|
||||
}
|
||||
#endif
|
||||
|
||||
// For when you know it's an opcode or operand and, therefore, just a normal RAM/ROM fetch
|
||||
static inline byte memory_Read_Fast(word addr)
|
||||
{
|
||||
return memory_ram[addr];
|
||||
}
|
||||
#define memory_Read_Fast(addr) memory_ram[(addr)]
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Push
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_Push(byte data)
|
||||
{
|
||||
//memory_Write(sally_s + 256, data);
|
||||
memory_ram[sally_s + 256] = data;
|
||||
memory_Write(sally_s | 256, data); // This could also write one of the mirrors...
|
||||
sally_s--;
|
||||
}
|
||||
|
||||
|
@ -103,55 +95,51 @@ static inline void sally_Push(byte data)
|
|||
static inline byte sally_Pop( )
|
||||
{
|
||||
sally_s++;
|
||||
return memory_ram[sally_s + 256];
|
||||
return memory_ram[sally_s | 256];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Flags
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_Flags(byte data)
|
||||
static inline __attribute__((always_inline)) void sally_Flags(byte data)
|
||||
{
|
||||
sally_p = (sally_p & ~(_fN | _fZ)) | ((data) & _fN) | (((data) == 0) ? _fZ : 0);
|
||||
sally_p = (sally_p & ~(_fN | _fZ)) | (data ? (data & _fN) : _fZ);
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void sally_FlagsFastCmp(byte data) // For faster compare handling...
|
||||
{
|
||||
sally_p = (sally_p & ~(_fN | _fZ | _fC)) | (data ? (data & _fN) : (_fZ | _fC));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Branch
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_Branch(byte branch) {
|
||||
if(branch) {
|
||||
pair temp = sally_pc;
|
||||
static inline __attribute__((always_inline)) void sally_Branch(byte branch)
|
||||
{
|
||||
if (likely(branch))
|
||||
{
|
||||
uint carry = sally_pc.w;
|
||||
sally_pc.w += (signed char)sally_address.b.l;
|
||||
|
||||
if(temp.b.h != sally_pc.b.h) {
|
||||
sally_cyclesX4 += 8;
|
||||
}
|
||||
else {
|
||||
sally_cyclesX4 += 4;
|
||||
}
|
||||
if ((carry ^ sally_pc.w) & 0x100) sally_cyclesX4 += 4; // Add an extra 4 cycles if we've crossed a page boundary
|
||||
}
|
||||
else // 95% of the time, the branch is not taken... so we've built into the cycle table the assumption the branch was taken and we back off 4 cycles if not
|
||||
{
|
||||
sally_cyclesX4 -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Delay
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_Delay(byte delta) {
|
||||
#if 0
|
||||
pair address1 = sally_address;
|
||||
address1.w -= delta;
|
||||
if(address1.b.h != sally_address.b.h) {
|
||||
sally_cyclesX4 += 4;
|
||||
}
|
||||
#else
|
||||
if (((word)sally_address.b.l + (word)delta) > 255) sally_cyclesX4 += 4;
|
||||
#endif
|
||||
static inline __attribute__((always_inline)) void sally_Delay(byte delta) {
|
||||
if (((word)sally_address.b.l + (word)delta) & 0xFF00) sally_cyclesX4 += 4;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Absolute
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_Absolute( ) {
|
||||
sally_address.b.l = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.w = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.b.h = memory_Read_Fast(sally_pc.w++);
|
||||
}
|
||||
|
||||
|
@ -159,7 +147,7 @@ static inline void sally_Absolute( ) {
|
|||
// AbsoluteX
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_AbsoluteX( ) {
|
||||
sally_address.b.l = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.w = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.b.h = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.w += sally_x;
|
||||
}
|
||||
|
@ -168,7 +156,7 @@ static inline void sally_AbsoluteX( ) {
|
|||
// AbsoluteY
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_AbsoluteY( ) {
|
||||
sally_address.b.l = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.w = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.b.h = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.w += sally_y;
|
||||
}
|
||||
|
@ -184,18 +172,18 @@ static inline void sally_Immediate( ) {
|
|||
// Indirect
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_Indirect( ) {
|
||||
pair base;
|
||||
base.b.l = memory_Read_Fast(sally_pc.w++);
|
||||
lpair base;
|
||||
base.w = memory_Read_Fast(sally_pc.w++);
|
||||
base.b.h = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.b.l = memory_Read_Fast(base.w);
|
||||
sally_address.b.h = memory_Read_Fast(base.w + 1);
|
||||
sally_address.w = memory_Read(base.w);
|
||||
sally_address.b.h = memory_Read(base.w + 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IndirectX
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_IndirectX( ) {
|
||||
sally_address.b.l = memory_Read_Fast(sally_pc.w++) + sally_x;
|
||||
sally_address.w = memory_Read_Fast(sally_pc.w++) + sally_x;
|
||||
sally_address.b.h = memory_Read_Fast(sally_address.b.l + 1);
|
||||
sally_address.b.l = memory_Read_Fast(sally_address.b.l);
|
||||
}
|
||||
|
@ -204,7 +192,7 @@ static inline void sally_IndirectX( ) {
|
|||
// IndirectY
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_IndirectY( ) {
|
||||
sally_address.b.l = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.w = memory_Read_Fast(sally_pc.w++);
|
||||
sally_address.b.h = memory_Read_Fast(sally_address.b.l + 1);
|
||||
sally_address.b.l = memory_Read_Fast(sally_address.b.l);
|
||||
sally_address.w += sally_y;
|
||||
|
@ -243,7 +231,7 @@ static inline void sally_ZeroPageY( ) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// ADC
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_ADC( ) {
|
||||
static void sally_ADC( ) {
|
||||
byte data = memory_Read(sally_address.w);
|
||||
if(sally_p & _fD) {
|
||||
word al = (sally_a & 15) + (data & 15) + (sally_p & _fC);
|
||||
|
@ -289,7 +277,7 @@ static inline void sally_ADC( ) {
|
|||
sally_a = (ah << 4) | (al & 15);
|
||||
}
|
||||
else {
|
||||
pair temp;
|
||||
lpair temp;
|
||||
temp.w = sally_a + data + (sally_p & _fC);
|
||||
|
||||
if(temp.b.h) {
|
||||
|
@ -470,8 +458,8 @@ static inline void sally_CLV( ) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// CMP
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_CMP( ) {
|
||||
byte data = memory_Read_Fast(sally_address.w);//memory_Read(sally_address.w);
|
||||
static inline __attribute__((always_inline)) void sally_CMP( ) {
|
||||
byte data = memory_Read(sally_address.w);
|
||||
|
||||
if(sally_a >= data) {
|
||||
sally_p |= _fC;
|
||||
|
@ -518,8 +506,8 @@ static inline void sally_CPY( ) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// DEC
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_DEC( ) {
|
||||
byte data = memory_Read_Fast(sally_address.w);
|
||||
static void sally_DEC( ) {
|
||||
byte data = memory_Read(sally_address.w);
|
||||
memory_Write(sally_address.w, --data);
|
||||
sally_Flags(data);
|
||||
}
|
||||
|
@ -549,8 +537,8 @@ static inline void sally_EOR( ) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// INC
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_INC( ) {
|
||||
byte data = memory_Read_Fast(sally_address.w);
|
||||
static void sally_INC( ) {
|
||||
byte data = memory_Read(sally_address.w);
|
||||
memory_Write(sally_address.w, ++data);
|
||||
sally_Flags(data);
|
||||
}
|
||||
|
@ -590,11 +578,18 @@ static inline void sally_JSR( ) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// LDA
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_LDA( ) {
|
||||
static inline __attribute__((always_inline)) void sally_LDA( ) {
|
||||
sally_a = memory_Read(sally_address.w);
|
||||
sally_Flags(sally_a);
|
||||
}
|
||||
|
||||
// Same as sally_LDA() above but when you know we are in basic memory_ram[]
|
||||
static inline __attribute__((always_inline)) void sally_LDA_fast( ) {
|
||||
sally_a = memory_Read_Fast(sally_address.w);
|
||||
sally_Flags(sally_a);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LDX
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -603,6 +598,12 @@ static inline void sally_LDX( ) {
|
|||
sally_Flags(sally_x);
|
||||
}
|
||||
|
||||
// Same as sally_LDX() above but when you know we are in basic memory_ram[]
|
||||
static inline void sally_LDX_fast( ) {
|
||||
sally_x = memory_Read_Fast(sally_address.w);
|
||||
sally_Flags(sally_x);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LDY
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -611,6 +612,12 @@ static inline void sally_LDY( ) {
|
|||
sally_Flags(sally_y);
|
||||
}
|
||||
|
||||
// Same as sally_LDY() above but when you know we are in basic memory_ram[]
|
||||
static inline void sally_LDY_fast( ) {
|
||||
sally_y = memory_Read_Fast(sally_address.w);
|
||||
sally_Flags(sally_y);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LSRA
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -774,7 +781,7 @@ static inline void sally_RTS( ) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// SBC
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_SBC( ) {
|
||||
static void sally_SBC( ) {
|
||||
byte data = memory_Read(sally_address.w);
|
||||
|
||||
if(sally_p & _fD) {
|
||||
|
@ -790,7 +797,7 @@ static inline void sally_SBC( ) {
|
|||
ah -= 6;
|
||||
}
|
||||
|
||||
pair temp;
|
||||
lpair temp;
|
||||
temp.w = sally_a - data - !(sally_p & _fC);
|
||||
|
||||
if(!temp.b.h) {
|
||||
|
@ -811,7 +818,7 @@ static inline void sally_SBC( ) {
|
|||
sally_a = (ah << 4) | (al & 15);
|
||||
}
|
||||
else {
|
||||
pair temp;
|
||||
lpair temp;
|
||||
temp.w = sally_a - data - !(sally_p & _fC);
|
||||
|
||||
if(!temp.b.h) {
|
||||
|
@ -864,7 +871,7 @@ static inline void sally_STA( ) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// STX
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void sally_stx( ) {
|
||||
static inline void sally_STX( ) {
|
||||
memory_Write(sally_address.w, sally_x);
|
||||
}
|
||||
|
||||
|
@ -922,6 +929,18 @@ static inline void sally_TYA( ) {
|
|||
sally_Flags(sally_a);
|
||||
}
|
||||
|
||||
|
||||
static inline void sally_SAX( ) {
|
||||
sally_STA();
|
||||
sally_STX();
|
||||
}
|
||||
|
||||
|
||||
static inline void sally_DCP( ) {
|
||||
sally_DEC();
|
||||
sally_CMP();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -932,6 +951,7 @@ void sally_Reset( ) {
|
|||
sally_p = _fT;
|
||||
sally_s = 0;
|
||||
sally_pc.w = 0;
|
||||
last_illegal_opcode = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -958,25 +978,9 @@ uint sally_ExecuteNMI( ) {
|
|||
return 7;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Execute IRQ
|
||||
// ----------------------------------------------------------------------------
|
||||
uint sally_ExecuteIRQ( ) {
|
||||
if(!(sally_p & _fI)) {
|
||||
sally_Push(sally_pc.b.h);
|
||||
sally_Push(sally_pc.b.l);
|
||||
sally_p &= ~_fB;
|
||||
sally_Push(sally_p);
|
||||
sally_p |= _fI;
|
||||
sally_pc.b.l = memory_ram[SALLY_IRQ.L];
|
||||
sally_pc.b.h = memory_ram[SALLY_IRQ.H];
|
||||
}
|
||||
return 7;
|
||||
}
|
||||
|
||||
extern uint prosystem_cycles;
|
||||
|
||||
void sally_Execute(unsigned int cycles )
|
||||
ITCM_CODE void sally_Execute(unsigned int cycles )
|
||||
{
|
||||
__label__
|
||||
l_0x00, l_0x01, l_0x02, l_0x03, l_0x04, l_0x05, l_0x06, l_0x07, l_0x08,
|
||||
|
@ -1045,6 +1049,7 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
while (prosystem_cycles<cycles)
|
||||
{
|
||||
register byte sally_opcode;
|
||||
sally_opcode = memory_ram[sally_pc.w++];
|
||||
sally_cyclesX4 = SALLY_CYCLESX4[sally_opcode];
|
||||
|
||||
|
@ -1413,18 +1418,21 @@ void sally_Execute(unsigned int cycles )
|
|||
goto next_inst;
|
||||
|
||||
l_0x84:
|
||||
sally_ZeroPage( );
|
||||
sally_STY( );
|
||||
memory_Write(memory_ram[sally_pc.w++], sally_y);
|
||||
//sally_ZeroPage( );
|
||||
//sally_STY( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x85:
|
||||
sally_ZeroPage( );
|
||||
sally_STA( );
|
||||
l_0x85:
|
||||
memory_Write(memory_ram[sally_pc.w++], sally_a);
|
||||
//sally_ZeroPage( );
|
||||
//sally_STA( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x86:
|
||||
sally_ZeroPage( );
|
||||
sally_stx( );
|
||||
memory_Write(memory_ram[sally_pc.w++], sally_x);
|
||||
//sally_ZeroPage( );
|
||||
//sally_STX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x88:
|
||||
|
@ -1447,7 +1455,7 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0x8e:
|
||||
sally_Absolute( );
|
||||
sally_stx( );
|
||||
sally_STX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x90:
|
||||
|
@ -1465,14 +1473,14 @@ void sally_Execute(unsigned int cycles )
|
|||
sally_STY( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x95:
|
||||
l_0x95:
|
||||
sally_ZeroPageX( );
|
||||
sally_STA( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x96:
|
||||
sally_ZeroPageY( );
|
||||
sally_stx( );
|
||||
sally_STX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x98:
|
||||
|
@ -1495,7 +1503,7 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0xa0:
|
||||
sally_Immediate( );
|
||||
sally_LDY( );
|
||||
sally_LDY_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xa1:
|
||||
|
@ -1505,22 +1513,22 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0xa2:
|
||||
sally_Immediate( );
|
||||
sally_LDX( );
|
||||
sally_LDX_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xa4:
|
||||
sally_ZeroPage( );
|
||||
sally_LDY( );
|
||||
sally_y = memory_Read_Fast(memory_Read_Fast(sally_pc.w++)); // Skip the intermediate set of sally_address to save a few CPU cycles
|
||||
sally_Flags(sally_y);
|
||||
goto next_inst;
|
||||
|
||||
l_0xa5:
|
||||
sally_ZeroPage( );
|
||||
sally_LDA( );
|
||||
l_0xa5:
|
||||
sally_a = memory_Read_Fast(memory_Read_Fast(sally_pc.w++)); // Skip the intermediate set of sally_address to save a few CPU cycles
|
||||
sally_Flags(sally_a);
|
||||
goto next_inst;
|
||||
|
||||
l_0xa6:
|
||||
sally_ZeroPage( );
|
||||
sally_LDX( );
|
||||
sally_x = memory_Read_Fast(memory_Read_Fast(sally_pc.w++)); // Skip the intermediate set of sally_address to save a few CPU cycles
|
||||
sally_Flags(sally_x);
|
||||
goto next_inst;
|
||||
|
||||
l_0xa8:
|
||||
|
@ -1529,7 +1537,7 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0xa9:
|
||||
sally_Immediate( );
|
||||
sally_LDA( );
|
||||
sally_LDA_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xaa:
|
||||
|
@ -1564,17 +1572,17 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0xb4:
|
||||
sally_ZeroPageX( );
|
||||
sally_LDY( );
|
||||
sally_LDY_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xb5:
|
||||
sally_ZeroPageX( );
|
||||
sally_LDA( );
|
||||
sally_LDA_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xb6:
|
||||
sally_ZeroPageY( );
|
||||
sally_LDX( );
|
||||
sally_LDX_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xb8:
|
||||
|
@ -1617,9 +1625,9 @@ void sally_Execute(unsigned int cycles )
|
|||
l_0xc1:
|
||||
sally_IndirectX( );
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
data_cmp = memory_Read(sally_address.w);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
goto next_inst;
|
||||
|
||||
l_0xc4:
|
||||
|
@ -1631,8 +1639,8 @@ void sally_Execute(unsigned int cycles )
|
|||
sally_ZeroPage( );
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
goto next_inst;
|
||||
|
||||
l_0xc6:
|
||||
|
@ -1646,10 +1654,10 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0xc9:
|
||||
sally_Immediate( );
|
||||
// sally_CMP( );
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
goto next_inst;
|
||||
|
||||
l_0xca:
|
||||
|
@ -1663,10 +1671,10 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0xcd:
|
||||
sally_Absolute( );
|
||||
// sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read(sally_address.w);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
goto next_inst;
|
||||
|
||||
l_0xce:
|
||||
|
@ -1681,19 +1689,37 @@ void sally_Execute(unsigned int cycles )
|
|||
|
||||
l_0xd1:
|
||||
sally_IndirectY( );
|
||||
// sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read(sally_address.w);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
sally_Delay(sally_y);
|
||||
goto next_inst;
|
||||
|
||||
l_0xd5:
|
||||
sally_ZeroPageX( );
|
||||
// sally_CMP( );
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
goto next_inst;
|
||||
|
||||
l_0xd9:
|
||||
sally_AbsoluteY( );
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read(sally_address.w);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
sally_Delay(sally_y);
|
||||
goto next_inst;
|
||||
|
||||
l_0xdd:
|
||||
sally_AbsoluteX( );
|
||||
//sally_CMP( );
|
||||
data_cmp = memory_Read(sally_address.w);
|
||||
sally_FlagsFastCmp(sally_a - data_cmp);
|
||||
if(sally_a > data_cmp) sally_p |= _fC;
|
||||
sally_Delay(sally_x);
|
||||
goto next_inst;
|
||||
|
||||
l_0xd6:
|
||||
|
@ -1705,24 +1731,6 @@ void sally_Execute(unsigned int cycles )
|
|||
sally_CLD( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xd9:
|
||||
sally_AbsoluteY( );
|
||||
// sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
sally_Delay(sally_y);
|
||||
goto next_inst;
|
||||
|
||||
l_0xdd:
|
||||
sally_AbsoluteX( );
|
||||
// sally_CMP( );
|
||||
data_cmp = memory_Read_Fast(sally_address.w);
|
||||
if(sally_a >= data_cmp) sally_p |= _fC; else sally_p &= ~_fC;
|
||||
sally_Flags(sally_a - data_cmp);
|
||||
sally_Delay(sally_x);
|
||||
goto next_inst;
|
||||
|
||||
l_0xde:
|
||||
sally_AbsoluteX( );
|
||||
sally_DEC( );
|
||||
|
@ -1837,10 +1845,104 @@ void sally_Execute(unsigned int cycles )
|
|||
sally_p |= _fC;
|
||||
}
|
||||
else {
|
||||
sally_p = (sally_p & ~_fC) & 0xFF;
|
||||
sally_p = (sally_p & ~_fC);
|
||||
}
|
||||
goto next_inst;
|
||||
|
||||
// --------------------------------------------------------------------------------------------------
|
||||
// Here starts the "undocumented" aka "illegal" OP Codes... but they are stable and sometimes used!
|
||||
// --------------------------------------------------------------------------------------------------
|
||||
l_0xa3:
|
||||
sally_IndirectX( );
|
||||
sally_LDA( );
|
||||
sally_LDX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xb3:
|
||||
sally_IndirectY( );
|
||||
sally_LDA( );
|
||||
sally_LDX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xaf:
|
||||
sally_Absolute( );
|
||||
sally_LDA( );
|
||||
sally_LDX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xbf:
|
||||
sally_AbsoluteY( );
|
||||
sally_LDA( );
|
||||
sally_LDX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xa7:
|
||||
sally_ZeroPage( );
|
||||
sally_LDA_fast( );
|
||||
sally_LDX_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xb7:
|
||||
sally_ZeroPageY( );
|
||||
sally_LDA_fast( );
|
||||
sally_LDX_fast( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x87:
|
||||
sally_ZeroPage( );
|
||||
sally_SAX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x97:
|
||||
sally_ZeroPageY( );
|
||||
sally_SAX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x83:
|
||||
sally_IndirectX( );
|
||||
sally_SAX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0x8f:
|
||||
sally_Absolute( );
|
||||
sally_SAX( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xc7:
|
||||
sally_ZeroPage( );
|
||||
sally_DCP( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xd7:
|
||||
sally_ZeroPageX( );
|
||||
sally_DCP( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xc3:
|
||||
sally_IndirectX( );
|
||||
sally_DCP( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xd3:
|
||||
sally_IndirectY( );
|
||||
sally_DCP( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xcf:
|
||||
sally_Absolute( );
|
||||
sally_DCP( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xdf:
|
||||
sally_AbsoluteX( );
|
||||
sally_DCP( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xdb:
|
||||
sally_AbsoluteY( );
|
||||
sally_DCP( );
|
||||
goto next_inst;
|
||||
|
||||
l_0xff:
|
||||
l_0xfc:
|
||||
l_0xfb:
|
||||
|
@ -1854,40 +1956,23 @@ l_0xeb:
|
|||
l_0xe7:
|
||||
l_0xe3:
|
||||
l_0xe2:
|
||||
l_0xdf:
|
||||
l_0xdc:
|
||||
l_0xdb:
|
||||
l_0xda:
|
||||
l_0xd7:
|
||||
l_0xd4:
|
||||
l_0xd3:
|
||||
l_0xd2:
|
||||
l_0xcf:
|
||||
l_0xcb:
|
||||
l_0xc7:
|
||||
l_0xc3:
|
||||
l_0xc2:
|
||||
l_0xbf:
|
||||
l_0xbb:
|
||||
l_0xb7:
|
||||
l_0xb3:
|
||||
l_0xb2:
|
||||
l_0xaf:
|
||||
l_0xab:
|
||||
l_0xa7:
|
||||
l_0xa3:
|
||||
l_0x9f:
|
||||
l_0x9e:
|
||||
l_0x9c:
|
||||
l_0x9b:
|
||||
l_0x97:
|
||||
l_0x93:
|
||||
l_0x92:
|
||||
l_0x8f:
|
||||
l_0x8b:
|
||||
l_0x89:
|
||||
l_0x87:
|
||||
l_0x83:
|
||||
l_0x82:
|
||||
l_0x80:
|
||||
l_0x7f:
|
||||
|
@ -1943,20 +2028,24 @@ l_0x07:
|
|||
l_0x04:
|
||||
l_0x03:
|
||||
l_0x02:
|
||||
|
||||
last_illegal_opcode = sally_opcode;
|
||||
next_inst:
|
||||
prosystem_cycles += sally_cyclesX4;
|
||||
#ifndef DS_LITE
|
||||
if(riot_timing)
|
||||
if (riot_and_wsync)
|
||||
{
|
||||
riot_UpdateTimer(sally_cyclesX4 >> 2);
|
||||
if (riot_and_wsync & 1) // Will only write true here if cartridge_uses_wsync is true in Memory.c
|
||||
{
|
||||
prosystem_cycles = CYCLES_PER_SCANLINE; // And reset back to a full line of cycles
|
||||
memory_ram[WSYNC] = false; // Clear the wsync flag - game can set this again on the next scanline
|
||||
riot_and_wsync &= 0xFE; // reset the wsync bit
|
||||
break; // And we're out...
|
||||
}
|
||||
else
|
||||
{
|
||||
riot_UpdateTimer(sally_cyclesX4 >> 2);
|
||||
}
|
||||
}
|
||||
if(memory_ram[WSYNC]) // Will only write true here if cartridge_uses_wsync is true in Memory.c
|
||||
{
|
||||
prosystem_cycles = 456;
|
||||
memory_ram[WSYNC] = false;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
|
@ -31,17 +31,27 @@
|
|||
#include "shared.h"
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
int32 w;
|
||||
struct {
|
||||
byte l;
|
||||
byte h;
|
||||
byte b2;
|
||||
byte b3;
|
||||
} b;
|
||||
} PCUnion;
|
||||
|
||||
extern void sally_Reset( );
|
||||
extern uint sally_ExecuteInstruction( );
|
||||
extern uint sally_ExecuteRES( );
|
||||
extern uint sally_ExecuteNMI( );
|
||||
extern uint sally_ExecuteIRQ( );
|
||||
extern byte sally_a;
|
||||
extern byte sally_x;
|
||||
extern byte sally_y;
|
||||
extern byte sally_p;
|
||||
extern byte sally_s;
|
||||
extern pair sally_pc;
|
||||
extern uint sally_p;
|
||||
extern uint sally_s;
|
||||
extern bool wsync_happened;
|
||||
|
||||
extern void sally_Execute(unsigned int cycles );
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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 "ProSystem.h"
|
||||
#include "Sound.h"
|
||||
#define SOUND_SOURCE "Sound.cpp"
|
||||
|
||||
unsigned char sound_buffer[SNDLENGTH]; // Sound buffer
|
||||
|
||||
unsigned int targetIndex = 0;
|
||||
|
||||
void processSound(register unsigned char *buffer)
|
||||
{
|
||||
// Handled directly in sound interrupt routine in a7800utils.c
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Sound.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
#define SNDLENGTH (4096)
|
||||
|
||||
extern unsigned char sound_buffer[SNDLENGTH]; // Sound buffer
|
||||
|
||||
extern bool sound_Store();
|
||||
extern void processSound(register unsigned char *buffer);
|
||||
|
||||
#endif
|
|
@ -38,38 +38,33 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Tia.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Sound.h"
|
||||
#include "Tia.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// I've extended these by 1 each so that we can do simple AND rather than %-Modulo which
|
||||
// gains us some speed and sacrifices very little in terms of sound processing...
|
||||
// ----------------------------------------------------------------------------------------
|
||||
#define TIA_POLY4_SIZE 15
|
||||
#define TIA_POLY5_SIZE 31
|
||||
#define TIA_POLY9_SIZE 511
|
||||
|
||||
byte tia_buffer[SNDLENGTH] = {0};
|
||||
int tiaBufIdx = 0;
|
||||
|
||||
static const byte TIA_POLY4[ ] = {1,1,0,1,1,1,0,0,0,0,1,0,1,0,0};
|
||||
static const byte TIA_POLY5[ ] = {0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1};
|
||||
static const byte TIA_POLY9[ ] = {0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,0,1,0,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,1,1,0,0,1,1,0,1,1,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,1,1,0,0,1,1,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,1,1,0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,1,1,0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1,1,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,1,1,0,0,1,0,0,1,0,1,1,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,0,1,0,0,1,0,1,0,1,0,1,1,1,0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0};
|
||||
static const byte TIA_DIV31[ ] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
static byte tia_volume[2] = {0};
|
||||
static byte tia_counterMax[2] = {0};
|
||||
static byte tia_counter[2] = {0};
|
||||
byte tia_audc[2] = {0};
|
||||
byte tia_audf[2] = {0};
|
||||
byte tia_audv[2] = {0};
|
||||
static byte tia_poly4Cntr[2] = {0};
|
||||
static byte tia_poly5Cntr[2] = {0};
|
||||
static uint tia_poly9Cntr[2] = {0};
|
||||
u32 tiaBufIdx __attribute__((section(".dtcm"))) = 0;
|
||||
u16 tia_buffer[SNDLENGTH] __attribute__((section(".dtcm"))) = {0};
|
||||
byte tia_volume[2] __attribute__((section(".dtcm"))) = {0};
|
||||
uint tia_counter[2] __attribute__((section(".dtcm"))) = {0};
|
||||
uint tia_counterMax[2] __attribute__((section(".dtcm"))) = {0};
|
||||
byte TIA_POLY4[ ] __attribute__((section(".dtcm"))) = {1,1,0,1,1,1,0,0,0,0,1,0,1,0,0};
|
||||
byte TIA_POLY5[ ] __attribute__((section(".dtcm"))) = {0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1};
|
||||
static byte TIA_POLY9[ ] __attribute__((section(".dtcm"))) = {0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,0,1,0,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,1,1,0,0,1,1,0,1,1,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,1,1,0,0,1,1,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,1,1,0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,1,1,0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1,1,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,1,1,0,0,1,0,0,1,0,1,1,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,0,1,0,0,1,0,1,0,1,0,1,1,1,0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0};
|
||||
static byte TIA_DIV31[ ] __attribute__((section(".dtcm"))) = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
byte tia_audc[2] __attribute__((section(".dtcm"))) = {0};
|
||||
byte tia_audf[2] __attribute__((section(".dtcm"))) = {0};
|
||||
byte tia_audv[2] __attribute__((section(".dtcm"))) = {0};
|
||||
static byte tia_poly4Cntr[2] __attribute__((section(".dtcm"))) = {0};
|
||||
static byte tia_poly5Cntr[2] __attribute__((section(".dtcm"))) = {0};
|
||||
static u16 tia_poly9Cntr[2] __attribute__((section(".dtcm"))) = {0};
|
||||
u16 tia_wait __attribute__((section(".dtcm"))) = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ProcessChannel
|
||||
// ----------------------------------------------------------------------------
|
||||
static void tia_ProcessChannel0(void)
|
||||
static ITCM_CODE void tia_ProcessChannel0(void)
|
||||
{
|
||||
tia_poly5Cntr[0] = (tia_poly5Cntr[0] + 1) % TIA_POLY5_SIZE;
|
||||
if(((tia_audc[0] & 2) == 0) || (((tia_audc[0] & 1) == 0) && TIA_DIV31[tia_poly5Cntr[0]]) || (((tia_audc[0] & 1) == 1) && TIA_POLY5[tia_poly5Cntr[0]]))
|
||||
|
@ -98,7 +93,7 @@ static void tia_ProcessChannel0(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void tia_ProcessChannel1(void)
|
||||
static ITCM_CODE void tia_ProcessChannel1(void)
|
||||
{
|
||||
tia_poly5Cntr[1] = (tia_poly5Cntr[1] + 1) % TIA_POLY5_SIZE;
|
||||
if(((tia_audc[1] & 2) == 0) || (((tia_audc[1] & 1) == 0) && TIA_DIV31[tia_poly5Cntr[1]]) || (((tia_audc[1] & 1) == 1) && TIA_POLY5[tia_poly5Cntr[1]]))
|
||||
|
@ -146,6 +141,7 @@ void tia_Reset( ) {
|
|||
tia_poly9Cntr[index] = 0;
|
||||
}
|
||||
tia_Clear( );
|
||||
tia_wait = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -158,92 +154,8 @@ void tia_Clear( ) {
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetRegister
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_SetRegister(word address, byte data)
|
||||
{
|
||||
byte channel=0;
|
||||
byte frequency;
|
||||
|
||||
switch(address) {
|
||||
case AUDC0:
|
||||
tia_audc[0] = data & 15;
|
||||
break;
|
||||
case AUDC1:
|
||||
tia_audc[1] = data & 15;
|
||||
channel = 1;
|
||||
break;
|
||||
case AUDF0:
|
||||
tia_audf[0] = data & 31;
|
||||
break;
|
||||
case AUDF1:
|
||||
tia_audf[1] = data & 31;
|
||||
channel = 1;
|
||||
break;
|
||||
case AUDV0:
|
||||
tia_audv[0] = (data & 15) << 2;
|
||||
break;
|
||||
case AUDV1:
|
||||
tia_audv[1] = (data & 15) << 2;
|
||||
channel = 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if(tia_audc[channel] == 0)
|
||||
{
|
||||
frequency = 0;
|
||||
tia_volume[channel] = tia_audv[channel];
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = tia_audf[channel] + 1;
|
||||
if(tia_audc[channel] > 11)
|
||||
{
|
||||
frequency *= 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(frequency != tia_counterMax[channel])
|
||||
{
|
||||
tia_counterMax[channel] = frequency;
|
||||
if(tia_counter[channel] == 0 || frequency == 0)
|
||||
{
|
||||
tia_counter[channel] = frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tia_MemoryChannel(byte channel)
|
||||
{
|
||||
byte frequency = 0;
|
||||
if(tia_audc[channel] == 0)
|
||||
{
|
||||
tia_volume[channel] = tia_audv[channel];
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = tia_audf[channel] + 1;
|
||||
if(tia_audc[channel] > 11)
|
||||
{
|
||||
frequency *= 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(frequency != tia_counterMax[channel])
|
||||
{
|
||||
tia_counterMax[channel] = frequency;
|
||||
if(tia_counter[channel] == 0 || frequency == 0)
|
||||
{
|
||||
tia_counter[channel] = frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Same as TIA_Process but designed for Pokey integration...
|
||||
int TIA_Sample(void)
|
||||
ITCM_CODE int TIA_Sample(void)
|
||||
{
|
||||
if(tia_counter[0] > 1)
|
||||
{
|
||||
|
@ -269,10 +181,13 @@ int TIA_Sample(void)
|
|||
// --------------------------------------------------------------------------------------
|
||||
// Process
|
||||
// --------------------------------------------------------------------------------------
|
||||
void tia_Process(uint length)
|
||||
ITCM_CODE void tia_Process(void)
|
||||
{
|
||||
uint index;
|
||||
for(index = 0; index < length; index++)
|
||||
u32 samp[2];
|
||||
|
||||
if (tia_wait) return;
|
||||
|
||||
for(u8 index = 0; index < 2; index++)
|
||||
{
|
||||
if(tia_counter[0] > 1)
|
||||
{
|
||||
|
@ -292,7 +207,46 @@ void tia_Process(uint length)
|
|||
tia_counter[1] = tia_counterMax[1];
|
||||
tia_ProcessChannel1();
|
||||
}
|
||||
tia_buffer[tiaBufIdx] = ((tia_volume[0] + tia_volume[1]));
|
||||
tiaBufIdx = (tiaBufIdx+1) & (SNDLENGTH-1);
|
||||
samp[index] = ((tia_volume[0] + tia_volume[1]));
|
||||
}
|
||||
|
||||
// We have filled the buffer... let the buffer drain a bit
|
||||
if (((tiaBufIdx+1) & (SNDLENGTH-1)) == myTiaBufIdx)
|
||||
{
|
||||
tia_wait = (SNDLENGTH >> 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_buffer[tiaBufIdx++] = (samp[1] << 8) | (samp[0]);
|
||||
tiaBufIdx &= (SNDLENGTH-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ITCM_CODE u16 tia_ProcessNow(void)
|
||||
{
|
||||
u32 samp[2];
|
||||
for(u8 index = 0; index < 2; index++)
|
||||
{
|
||||
if(tia_counter[0] > 1)
|
||||
{
|
||||
tia_counter[0]--;
|
||||
}
|
||||
else if(tia_counter[0] == 1)
|
||||
{
|
||||
tia_counter[0] = tia_counterMax[0];
|
||||
tia_ProcessChannel0();
|
||||
}
|
||||
if(tia_counter[1] > 1)
|
||||
{
|
||||
tia_counter[1]--;
|
||||
}
|
||||
else if(tia_counter[1] == 1)
|
||||
{
|
||||
tia_counter[1] = tia_counterMax[1];
|
||||
tia_ProcessChannel1();
|
||||
}
|
||||
samp[index] = ((tia_volume[0] + tia_volume[1]));
|
||||
}
|
||||
return (u16)((samp[1] << 8) | (samp[0]));
|
||||
}
|
|
@ -45,6 +45,10 @@
|
|||
|
||||
#include "shared.h"
|
||||
|
||||
#define SNDLENGTH (1024)
|
||||
|
||||
extern u16 tia_buffer[];
|
||||
|
||||
extern byte tia_audc[2];
|
||||
extern byte tia_audf[2];
|
||||
extern byte tia_audv[2];
|
||||
|
@ -52,9 +56,40 @@ extern byte tia_audv[2];
|
|||
|
||||
extern void tia_Reset( );
|
||||
extern void tia_SetRegister(word address, byte data);
|
||||
extern void tia_MemoryChannel(byte channel);
|
||||
extern void tia_Clear( );
|
||||
extern void tia_Process(uint length);
|
||||
extern byte tia_buffer[];
|
||||
extern void tia_Process(void);
|
||||
extern u16 tia_ProcessNow(void);
|
||||
extern byte tia_volume[2];
|
||||
extern uint tia_counter[2];
|
||||
extern uint tia_counterMax[2];
|
||||
extern u16 tia_wait;
|
||||
extern u32 myTiaBufIdx;
|
||||
|
||||
|
||||
inline void tia_MemoryChannel(byte channel)
|
||||
{
|
||||
byte frequency = 0;
|
||||
if(tia_audc[channel] == 0)
|
||||
{
|
||||
tia_volume[channel] = tia_audv[channel];
|
||||
}
|
||||
else
|
||||
{
|
||||
frequency = tia_audf[channel] + 1;
|
||||
if(tia_audc[channel] > 11)
|
||||
{
|
||||
frequency *= 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(frequency != tia_counterMax[channel])
|
||||
{
|
||||
tia_counterMax[channel] = frequency;
|
||||
if(tia_counter[channel] == 0 || frequency == 0)
|
||||
{
|
||||
tia_counter[channel] = frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,21 +3,10 @@
|
|||
|
||||
#include <nds.h>
|
||||
|
||||
//#define SYSVID_WIDTH 320
|
||||
//#define SYSVID_HEIGHT 223
|
||||
|
||||
//typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern unsigned short *bufVideo; // Video buffer
|
||||
|
||||
extern char gameName[256];
|
||||
extern unsigned int gameCRC;
|
||||
extern uint video_height;
|
||||
extern word atari_pal16[256];
|
||||
|
||||
extern void system_loadcfg(char *cfg_name);
|
||||
extern void system_savecfg(char *cfg_name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include <nds.h>
|
||||
#include <stdio.h>
|
||||
#include <maxmod9.h>
|
||||
|
||||
#include "a7800utils.h"
|
||||
#include "soundbank.h"
|
||||
|
||||
#include "mus_intro_wav.h"
|
||||
#include "pdev_tbg0.h"
|
||||
|
@ -15,7 +17,6 @@ void vblankIntro() {
|
|||
|
||||
// Intro with portabledev logo
|
||||
void intro_logo(void) {
|
||||
int soundId=-1;
|
||||
bool bOK;
|
||||
|
||||
// Init graphics
|
||||
|
@ -34,6 +35,8 @@ void intro_logo(void) {
|
|||
REG_BLDCNT = BLEND_FADE_BLACK | BLEND_SRC_BG0 | BLEND_DST_BG0; REG_BLDY = 16;
|
||||
REG_BLDCNT_SUB = BLEND_FADE_BLACK | BLEND_SRC_BG0 | BLEND_DST_BG0; REG_BLDY_SUB = 16;
|
||||
|
||||
mmEffect(SFX_MUS_INTRO);
|
||||
|
||||
// Show portabledev
|
||||
decompress(pdev_tbg0Tiles, bgGetGfxPtr(bg1), LZ77Vram);
|
||||
decompress(pdev_tbg0Map, (void*) bgGetMapPtr(bg1), LZ77Vram);
|
||||
|
@ -45,8 +48,6 @@ void intro_logo(void) {
|
|||
|
||||
FadeToColor(0,BLEND_FADE_BLACK | BLEND_SRC_BG0 | BLEND_DST_BG0,3,0,3);
|
||||
|
||||
soundId = soundPlaySample((const void *) mus_intro_wav, SoundFormat_ADPCM, mus_intro_wav_size, 22050, 127, 64, false, 0);
|
||||
|
||||
bOK=false;
|
||||
while (!bOK) { if ( !(keysCurrent() & 0x1FFF) ) bOK=true; } // 0x1FFF = key or pen
|
||||
vusCptVBL=0;bOK=false;
|
||||
|
@ -55,5 +56,4 @@ void intro_logo(void) {
|
|||
while (!bOK) { if ( !(keysCurrent() & 0x1FFF) ) bOK=true; }
|
||||
|
||||
FadeToColor(1,BLEND_FADE_WHITE | BLEND_SRC_BG0 | BLEND_DST_BG0,3,16,3);
|
||||
if (soundId!=-1) soundKill(soundId);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,40 @@
|
|||
// =====================================================================================
|
||||
// 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.
|
||||
// =====================================================================================
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <fat.h>
|
||||
#include <nds.h>
|
||||
#include <maxmod9.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "intro.h"
|
||||
#include "config.h"
|
||||
#include "a7800utils.h"
|
||||
#include "soundbank.h"
|
||||
|
||||
// Program entry point
|
||||
int main(int argc, char **argv)
|
||||
|
@ -28,14 +58,26 @@ int main(int argc, char **argv)
|
|||
// Intro and main screen
|
||||
intro_logo();
|
||||
dsInitScreenMain();
|
||||
etatEmu = A7800_MENUINIT;
|
||||
emu_state = A7800_MENUINIT;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
LoadConfig();
|
||||
|
||||
bios_check_and_load();
|
||||
|
||||
//load rom file via args if a rom path is supplied
|
||||
if(argc > 1)
|
||||
{
|
||||
dsShowScreenMain();
|
||||
dsShowScreenMain(true);
|
||||
dsLoadGame(argv[1]);
|
||||
etatEmu = A7800_PLAYINIT;
|
||||
emu_state = A7800_PLAYINIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
chdir("/roms"); // Try to start in roms area... doesn't matter if it fails
|
||||
chdir("a7800"); // And try to start in the subdir /a7800... doesn't matter if it fails.
|
||||
chdir("a78"); // And try to start in the subdir /a78... doesn't matter if it fails.
|
||||
}
|
||||
|
||||
// Main loop of emulation
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
914
arm9/source/printf.c
Normal file
|
@ -0,0 +1,914 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// \author (c) Marco Paland (info@paland.com)
|
||||
// 2014-2019, PALANDesign Hannover, Germany
|
||||
//
|
||||
// \license The MIT License (MIT)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
|
||||
// embedded systems with a very limited resources. These routines are thread
|
||||
// safe and reentrant!
|
||||
// Use this instead of the bloated standard/newlib printf cause these use
|
||||
// malloc for printf (and may not be thread safe).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "printf.h"
|
||||
|
||||
|
||||
// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the
|
||||
// printf_config.h header file
|
||||
// default: undefined
|
||||
#ifdef PRINTF_INCLUDE_CONFIG_H
|
||||
#include "printf_config.h"
|
||||
#endif
|
||||
|
||||
|
||||
// 'ntoa' conversion buffer size, this must be big enough to hold one converted
|
||||
// numeric number including padded zeros (dynamically created on stack)
|
||||
// default: 32 byte
|
||||
#ifndef PRINTF_NTOA_BUFFER_SIZE
|
||||
#define PRINTF_NTOA_BUFFER_SIZE 32U
|
||||
#endif
|
||||
|
||||
// 'ftoa' conversion buffer size, this must be big enough to hold one converted
|
||||
// float number including padded zeros (dynamically created on stack)
|
||||
// default: 32 byte
|
||||
#ifndef PRINTF_FTOA_BUFFER_SIZE
|
||||
#define PRINTF_FTOA_BUFFER_SIZE 32U
|
||||
#endif
|
||||
|
||||
// support for the floating point type (%f)
|
||||
// default: activated
|
||||
#ifndef PRINTF_DISABLE_SUPPORT_FLOAT
|
||||
#define PRINTF_SUPPORT_FLOAT
|
||||
#endif
|
||||
|
||||
// support for exponential floating point notation (%e/%g)
|
||||
// default: activated
|
||||
#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
|
||||
#define PRINTF_SUPPORT_EXPONENTIAL
|
||||
#endif
|
||||
|
||||
// define the default floating point precision
|
||||
// default: 6 digits
|
||||
#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
|
||||
#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
|
||||
#endif
|
||||
|
||||
// define the largest float suitable to print with %f
|
||||
// default: 1e9
|
||||
#ifndef PRINTF_MAX_FLOAT
|
||||
#define PRINTF_MAX_FLOAT 1e9
|
||||
#endif
|
||||
|
||||
// support for the long long types (%llu or %p)
|
||||
// default: activated
|
||||
#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
|
||||
#define PRINTF_SUPPORT_LONG_LONG
|
||||
#endif
|
||||
|
||||
// support for the ptrdiff_t type (%t)
|
||||
// ptrdiff_t is normally defined in <stddef.h> as long or long long type
|
||||
// default: activated
|
||||
#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
|
||||
#define PRINTF_SUPPORT_PTRDIFF_T
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// internal flag definitions
|
||||
#define FLAGS_ZEROPAD (1U << 0U)
|
||||
#define FLAGS_LEFT (1U << 1U)
|
||||
#define FLAGS_PLUS (1U << 2U)
|
||||
#define FLAGS_SPACE (1U << 3U)
|
||||
#define FLAGS_HASH (1U << 4U)
|
||||
#define FLAGS_UPPERCASE (1U << 5U)
|
||||
#define FLAGS_CHAR (1U << 6U)
|
||||
#define FLAGS_SHORT (1U << 7U)
|
||||
#define FLAGS_LONG (1U << 8U)
|
||||
#define FLAGS_LONG_LONG (1U << 9U)
|
||||
#define FLAGS_PRECISION (1U << 10U)
|
||||
#define FLAGS_ADAPT_EXP (1U << 11U)
|
||||
|
||||
|
||||
// import float.h for DBL_MAX
|
||||
#if defined(PRINTF_SUPPORT_FLOAT)
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
|
||||
// output function type
|
||||
typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen);
|
||||
|
||||
|
||||
// wrapper (used as buffer) for output function type
|
||||
typedef struct {
|
||||
void (*fct)(char character, void* arg);
|
||||
void* arg;
|
||||
} out_fct_wrap_type;
|
||||
|
||||
|
||||
// internal buffer output
|
||||
static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
|
||||
{
|
||||
if (idx < maxlen) {
|
||||
((char*)buffer)[idx] = character;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// internal null output
|
||||
static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
|
||||
{
|
||||
(void)character; (void)buffer; (void)idx; (void)maxlen;
|
||||
}
|
||||
|
||||
|
||||
// internal _putchar wrapper
|
||||
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
|
||||
{
|
||||
(void)buffer; (void)idx; (void)maxlen;
|
||||
if (character) {
|
||||
_putchar(character);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// internal output function wrapper
|
||||
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
|
||||
{
|
||||
(void)idx; (void)maxlen;
|
||||
if (character) {
|
||||
// buffer is the output fct pointer
|
||||
((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// internal secure strlen
|
||||
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
|
||||
static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
|
||||
{
|
||||
const char* s;
|
||||
for (s = str; *s && maxsize--; ++s);
|
||||
return (unsigned int)(s - str);
|
||||
}
|
||||
|
||||
|
||||
// internal test if char is a digit (0-9)
|
||||
// \return true if char is a digit
|
||||
static inline bool _is_digit(char ch)
|
||||
{
|
||||
return (ch >= '0') && (ch <= '9');
|
||||
}
|
||||
|
||||
|
||||
// internal ASCII string to unsigned int conversion
|
||||
static unsigned int _atoi(const char** str)
|
||||
{
|
||||
unsigned int i = 0U;
|
||||
while (_is_digit(**str)) {
|
||||
i = i * 10U + (unsigned int)(*((*str)++) - '0');
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
// output the specified string in reverse, taking care of any zero-padding
|
||||
static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
|
||||
{
|
||||
const size_t start_idx = idx;
|
||||
|
||||
// pad spaces up to given width
|
||||
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
|
||||
for (size_t i = len; i < width; i++) {
|
||||
out(' ', buffer, idx++, maxlen);
|
||||
}
|
||||
}
|
||||
|
||||
// reverse string
|
||||
while (len) {
|
||||
out(buf[--len], buffer, idx++, maxlen);
|
||||
}
|
||||
|
||||
// append pad spaces up to given width
|
||||
if (flags & FLAGS_LEFT) {
|
||||
while (idx - start_idx < width) {
|
||||
out(' ', buffer, idx++, maxlen);
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
// internal itoa format
|
||||
static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
|
||||
{
|
||||
// pad leading zeros
|
||||
if (!(flags & FLAGS_LEFT)) {
|
||||
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
|
||||
width--;
|
||||
}
|
||||
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
// handle hash
|
||||
if (flags & FLAGS_HASH) {
|
||||
if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
|
||||
len--;
|
||||
if (len && (base == 16U)) {
|
||||
len--;
|
||||
}
|
||||
}
|
||||
if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
|
||||
buf[len++] = 'x';
|
||||
}
|
||||
else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
|
||||
buf[len++] = 'X';
|
||||
}
|
||||
else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
|
||||
buf[len++] = 'b';
|
||||
}
|
||||
if (len < PRINTF_NTOA_BUFFER_SIZE) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
if (len < PRINTF_NTOA_BUFFER_SIZE) {
|
||||
if (negative) {
|
||||
buf[len++] = '-';
|
||||
}
|
||||
else if (flags & FLAGS_PLUS) {
|
||||
buf[len++] = '+'; // ignore the space if the '+' exists
|
||||
}
|
||||
else if (flags & FLAGS_SPACE) {
|
||||
buf[len++] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
|
||||
}
|
||||
|
||||
|
||||
// internal itoa for 'long' type
|
||||
static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
|
||||
{
|
||||
char buf[PRINTF_NTOA_BUFFER_SIZE];
|
||||
size_t len = 0U;
|
||||
|
||||
// no hash for 0 values
|
||||
if (!value) {
|
||||
flags &= ~FLAGS_HASH;
|
||||
}
|
||||
|
||||
// write if precision != 0 and value is != 0
|
||||
if (!(flags & FLAGS_PRECISION) || value) {
|
||||
do {
|
||||
const char digit = (char)(value % base);
|
||||
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
|
||||
value /= base;
|
||||
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
|
||||
}
|
||||
|
||||
|
||||
// internal itoa for 'long long' type
|
||||
#if defined(PRINTF_SUPPORT_LONG_LONG)
|
||||
static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
|
||||
{
|
||||
char buf[PRINTF_NTOA_BUFFER_SIZE];
|
||||
size_t len = 0U;
|
||||
|
||||
// no hash for 0 values
|
||||
if (!value) {
|
||||
flags &= ~FLAGS_HASH;
|
||||
}
|
||||
|
||||
// write if precision != 0 and value is != 0
|
||||
if (!(flags & FLAGS_PRECISION) || value) {
|
||||
do {
|
||||
const char digit = (char)(value % base);
|
||||
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
|
||||
value /= base;
|
||||
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
|
||||
}
|
||||
|
||||
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
|
||||
}
|
||||
#endif // PRINTF_SUPPORT_LONG_LONG
|
||||
|
||||
|
||||
#if defined(PRINTF_SUPPORT_FLOAT)
|
||||
|
||||
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
|
||||
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
|
||||
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
|
||||
#endif
|
||||
|
||||
|
||||
// internal ftoa for fixed decimal floating point
|
||||
static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
|
||||
{
|
||||
char buf[PRINTF_FTOA_BUFFER_SIZE];
|
||||
size_t len = 0U;
|
||||
double diff = 0.0;
|
||||
|
||||
// powers of 10
|
||||
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
||||
|
||||
// test for special values
|
||||
if (value != value)
|
||||
return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
|
||||
if (value < -DBL_MAX)
|
||||
return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
|
||||
if (value > DBL_MAX)
|
||||
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
|
||||
|
||||
// test for very large values
|
||||
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
|
||||
if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
|
||||
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
|
||||
return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
|
||||
#else
|
||||
return 0U;
|
||||
#endif
|
||||
}
|
||||
|
||||
// test for negative
|
||||
bool negative = false;
|
||||
if (value < 0) {
|
||||
negative = true;
|
||||
value = 0 - value;
|
||||
}
|
||||
|
||||
// set default precision, if not set explicitly
|
||||
if (!(flags & FLAGS_PRECISION)) {
|
||||
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
|
||||
}
|
||||
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
|
||||
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
|
||||
buf[len++] = '0';
|
||||
prec--;
|
||||
}
|
||||
|
||||
int whole = (int)value;
|
||||
double tmp = (value - whole) * pow10[prec];
|
||||
unsigned long frac = (unsigned long)tmp;
|
||||
diff = tmp - frac;
|
||||
|
||||
if (diff > 0.5) {
|
||||
++frac;
|
||||
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
|
||||
if (frac >= pow10[prec]) {
|
||||
frac = 0;
|
||||
++whole;
|
||||
}
|
||||
}
|
||||
else if (diff < 0.5) {
|
||||
}
|
||||
else if ((frac == 0U) || (frac & 1U)) {
|
||||
// if halfway, round up if odd OR if last digit is 0
|
||||
++frac;
|
||||
}
|
||||
|
||||
if (prec == 0U) {
|
||||
diff = value - (double)whole;
|
||||
if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
|
||||
// exactly 0.5 and ODD, then round up
|
||||
// 1.5 -> 2, but 2.5 -> 2
|
||||
++whole;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned int count = prec;
|
||||
// now do fractional part, as an unsigned number
|
||||
while (len < PRINTF_FTOA_BUFFER_SIZE) {
|
||||
--count;
|
||||
buf[len++] = (char)(48U + (frac % 10U));
|
||||
if (!(frac /= 10U)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// add extra 0s
|
||||
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
if (len < PRINTF_FTOA_BUFFER_SIZE) {
|
||||
// add decimal
|
||||
buf[len++] = '.';
|
||||
}
|
||||
}
|
||||
|
||||
// do whole part, number is reversed
|
||||
while (len < PRINTF_FTOA_BUFFER_SIZE) {
|
||||
buf[len++] = (char)(48 + (whole % 10));
|
||||
if (!(whole /= 10)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pad leading zeros
|
||||
if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
|
||||
if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
|
||||
width--;
|
||||
}
|
||||
while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
|
||||
buf[len++] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
if (len < PRINTF_FTOA_BUFFER_SIZE) {
|
||||
if (negative) {
|
||||
buf[len++] = '-';
|
||||
}
|
||||
else if (flags & FLAGS_PLUS) {
|
||||
buf[len++] = '+'; // ignore the space if the '+' exists
|
||||
}
|
||||
else if (flags & FLAGS_SPACE) {
|
||||
buf[len++] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
|
||||
}
|
||||
|
||||
|
||||
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
|
||||
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
|
||||
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
|
||||
{
|
||||
// check for NaN and special values
|
||||
if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
|
||||
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
|
||||
}
|
||||
|
||||
// determine the sign
|
||||
const bool negative = value < 0;
|
||||
if (negative) {
|
||||
value = -value;
|
||||
}
|
||||
|
||||
// default precision
|
||||
if (!(flags & FLAGS_PRECISION)) {
|
||||
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
|
||||
}
|
||||
|
||||
// determine the decimal exponent
|
||||
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
|
||||
union {
|
||||
uint64_t U;
|
||||
double F;
|
||||
} conv;
|
||||
|
||||
conv.F = value;
|
||||
int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2
|
||||
conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2)
|
||||
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
|
||||
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168);
|
||||
// now we want to compute 10^expval but we want to be sure it won't overflow
|
||||
exp2 = (int)(expval * 3.321928094887362 + 0.5);
|
||||
const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
|
||||
const double z2 = z * z;
|
||||
conv.U = (uint64_t)(exp2 + 1023) << 52U;
|
||||
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
|
||||
conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
|
||||
// correct for rounding errors
|
||||
if (value < conv.F) {
|
||||
expval--;
|
||||
conv.F /= 10;
|
||||
}
|
||||
|
||||
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
|
||||
unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U;
|
||||
|
||||
// in "%g" mode, "prec" is the number of *significant figures* not decimals
|
||||
if (flags & FLAGS_ADAPT_EXP) {
|
||||
// do we want to fall-back to "%f" mode?
|
||||
if ((value >= 1e-4) && (value < 1e6)) {
|
||||
if ((int)prec > expval) {
|
||||
prec = (unsigned)((int)prec - expval - 1);
|
||||
}
|
||||
else {
|
||||
prec = 0;
|
||||
}
|
||||
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
|
||||
// no characters in exponent
|
||||
minwidth = 0U;
|
||||
expval = 0;
|
||||
}
|
||||
else {
|
||||
// we use one sigfig for the whole part
|
||||
if ((prec > 0) && (flags & FLAGS_PRECISION)) {
|
||||
--prec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// will everything fit?
|
||||
unsigned int fwidth = width;
|
||||
if (width > minwidth) {
|
||||
// we didn't fall-back so subtract the characters required for the exponent
|
||||
fwidth -= minwidth;
|
||||
} else {
|
||||
// not enough characters, so go back to default sizing
|
||||
fwidth = 0U;
|
||||
}
|
||||
if ((flags & FLAGS_LEFT) && minwidth) {
|
||||
// if we're padding on the right, DON'T pad the floating part
|
||||
fwidth = 0U;
|
||||
}
|
||||
|
||||
// rescale the float value
|
||||
if (expval) {
|
||||
value /= conv.F;
|
||||
}
|
||||
|
||||
// output the floating part
|
||||
const size_t start_idx = idx;
|
||||
idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP);
|
||||
|
||||
// output the exponent part
|
||||
if (minwidth) {
|
||||
// output the exponential symbol
|
||||
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
|
||||
// output the exponent value
|
||||
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS);
|
||||
// might need to right-pad spaces
|
||||
if (flags & FLAGS_LEFT) {
|
||||
while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
#endif // PRINTF_SUPPORT_EXPONENTIAL
|
||||
#endif // PRINTF_SUPPORT_FLOAT
|
||||
|
||||
|
||||
// internal vsnprintf
|
||||
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
|
||||
{
|
||||
unsigned int flags, width, precision, n;
|
||||
size_t idx = 0U;
|
||||
|
||||
if (!buffer) {
|
||||
// use null output function
|
||||
out = _out_null;
|
||||
}
|
||||
|
||||
while (*format)
|
||||
{
|
||||
// format specifier? %[flags][width][.precision][length]
|
||||
if (*format != '%') {
|
||||
// no
|
||||
out(*format, buffer, idx++, maxlen);
|
||||
format++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// yes, evaluate it
|
||||
format++;
|
||||
}
|
||||
|
||||
// evaluate flags
|
||||
flags = 0U;
|
||||
do {
|
||||
switch (*format) {
|
||||
case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break;
|
||||
case '-': flags |= FLAGS_LEFT; format++; n = 1U; break;
|
||||
case '+': flags |= FLAGS_PLUS; format++; n = 1U; break;
|
||||
case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break;
|
||||
case '#': flags |= FLAGS_HASH; format++; n = 1U; break;
|
||||
default : n = 0U; break;
|
||||
}
|
||||
} while (n);
|
||||
|
||||
// evaluate width field
|
||||
width = 0U;
|
||||
if (_is_digit(*format)) {
|
||||
width = _atoi(&format);
|
||||
}
|
||||
else if (*format == '*') {
|
||||
const int w = va_arg(va, int);
|
||||
if (w < 0) {
|
||||
flags |= FLAGS_LEFT; // reverse padding
|
||||
width = (unsigned int)-w;
|
||||
}
|
||||
else {
|
||||
width = (unsigned int)w;
|
||||
}
|
||||
format++;
|
||||
}
|
||||
|
||||
// evaluate precision field
|
||||
precision = 0U;
|
||||
if (*format == '.') {
|
||||
flags |= FLAGS_PRECISION;
|
||||
format++;
|
||||
if (_is_digit(*format)) {
|
||||
precision = _atoi(&format);
|
||||
}
|
||||
else if (*format == '*') {
|
||||
const int prec = (int)va_arg(va, int);
|
||||
precision = prec > 0 ? (unsigned int)prec : 0U;
|
||||
format++;
|
||||
}
|
||||
}
|
||||
|
||||
// evaluate length field
|
||||
switch (*format) {
|
||||
case 'l' :
|
||||
flags |= FLAGS_LONG;
|
||||
format++;
|
||||
if (*format == 'l') {
|
||||
flags |= FLAGS_LONG_LONG;
|
||||
format++;
|
||||
}
|
||||
break;
|
||||
case 'h' :
|
||||
flags |= FLAGS_SHORT;
|
||||
format++;
|
||||
if (*format == 'h') {
|
||||
flags |= FLAGS_CHAR;
|
||||
format++;
|
||||
}
|
||||
break;
|
||||
#if defined(PRINTF_SUPPORT_PTRDIFF_T)
|
||||
case 't' :
|
||||
flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
|
||||
format++;
|
||||
break;
|
||||
#endif
|
||||
case 'j' :
|
||||
flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
|
||||
format++;
|
||||
break;
|
||||
case 'z' :
|
||||
flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
|
||||
format++;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
// evaluate specifier
|
||||
switch (*format) {
|
||||
case 'd' :
|
||||
case 'i' :
|
||||
case 'u' :
|
||||
case 'x' :
|
||||
case 'X' :
|
||||
case 'o' :
|
||||
case 'b' : {
|
||||
// set the base
|
||||
unsigned int base;
|
||||
if (*format == 'x' || *format == 'X') {
|
||||
base = 16U;
|
||||
}
|
||||
else if (*format == 'o') {
|
||||
base = 8U;
|
||||
}
|
||||
else if (*format == 'b') {
|
||||
base = 2U;
|
||||
}
|
||||
else {
|
||||
base = 10U;
|
||||
flags &= ~FLAGS_HASH; // no hash for dec format
|
||||
}
|
||||
// uppercase
|
||||
if (*format == 'X') {
|
||||
flags |= FLAGS_UPPERCASE;
|
||||
}
|
||||
|
||||
// no plus or space flag for u, x, X, o, b
|
||||
if ((*format != 'i') && (*format != 'd')) {
|
||||
flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
|
||||
}
|
||||
|
||||
// ignore '0' flag when precision is given
|
||||
if (flags & FLAGS_PRECISION) {
|
||||
flags &= ~FLAGS_ZEROPAD;
|
||||
}
|
||||
|
||||
// convert the integer
|
||||
if ((*format == 'i') || (*format == 'd')) {
|
||||
// signed
|
||||
if (flags & FLAGS_LONG_LONG) {
|
||||
#if defined(PRINTF_SUPPORT_LONG_LONG)
|
||||
const long long value = va_arg(va, long long);
|
||||
idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
|
||||
#endif
|
||||
}
|
||||
else if (flags & FLAGS_LONG) {
|
||||
const long value = va_arg(va, long);
|
||||
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
|
||||
}
|
||||
else {
|
||||
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int);
|
||||
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// unsigned
|
||||
if (flags & FLAGS_LONG_LONG) {
|
||||
#if defined(PRINTF_SUPPORT_LONG_LONG)
|
||||
idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
|
||||
#endif
|
||||
}
|
||||
else if (flags & FLAGS_LONG) {
|
||||
idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags);
|
||||
}
|
||||
else {
|
||||
const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int);
|
||||
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
|
||||
}
|
||||
}
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
#if defined(PRINTF_SUPPORT_FLOAT)
|
||||
case 'f' :
|
||||
case 'F' :
|
||||
if (*format == 'F') flags |= FLAGS_UPPERCASE;
|
||||
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
|
||||
format++;
|
||||
break;
|
||||
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'g':
|
||||
case 'G':
|
||||
if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
|
||||
if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
|
||||
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
|
||||
format++;
|
||||
break;
|
||||
#endif // PRINTF_SUPPORT_EXPONENTIAL
|
||||
#endif // PRINTF_SUPPORT_FLOAT
|
||||
case 'c' : {
|
||||
unsigned int l = 1U;
|
||||
// pre padding
|
||||
if (!(flags & FLAGS_LEFT)) {
|
||||
while (l++ < width) {
|
||||
out(' ', buffer, idx++, maxlen);
|
||||
}
|
||||
}
|
||||
// char output
|
||||
out((char)va_arg(va, int), buffer, idx++, maxlen);
|
||||
// post padding
|
||||
if (flags & FLAGS_LEFT) {
|
||||
while (l++ < width) {
|
||||
out(' ', buffer, idx++, maxlen);
|
||||
}
|
||||
}
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
|
||||
case 's' : {
|
||||
const char* p = va_arg(va, char*);
|
||||
unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1);
|
||||
// pre padding
|
||||
if (flags & FLAGS_PRECISION) {
|
||||
l = (l < precision ? l : precision);
|
||||
}
|
||||
if (!(flags & FLAGS_LEFT)) {
|
||||
while (l++ < width) {
|
||||
out(' ', buffer, idx++, maxlen);
|
||||
}
|
||||
}
|
||||
// string output
|
||||
while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
|
||||
out(*(p++), buffer, idx++, maxlen);
|
||||
}
|
||||
// post padding
|
||||
if (flags & FLAGS_LEFT) {
|
||||
while (l++ < width) {
|
||||
out(' ', buffer, idx++, maxlen);
|
||||
}
|
||||
}
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p' : {
|
||||
width = sizeof(void*) * 2U;
|
||||
flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE;
|
||||
#if defined(PRINTF_SUPPORT_LONG_LONG)
|
||||
const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
|
||||
if (is_ll) {
|
||||
idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags);
|
||||
#if defined(PRINTF_SUPPORT_LONG_LONG)
|
||||
}
|
||||
#endif
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
|
||||
case '%' :
|
||||
out('%', buffer, idx++, maxlen);
|
||||
format++;
|
||||
break;
|
||||
|
||||
default :
|
||||
out(*format, buffer, idx++, maxlen);
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// termination
|
||||
out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
|
||||
|
||||
// return written chars without terminating \0
|
||||
return (int)idx;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int printf_(const char* format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
char buffer[1];
|
||||
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int sprintf_(char* buffer, const char* format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int snprintf_(char* buffer, size_t count, const char* format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
const int ret = _vsnprintf(_out_buffer, buffer, count, format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int vprintf_(const char* format, va_list va)
|
||||
{
|
||||
char buffer[1];
|
||||
return _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
|
||||
}
|
||||
|
||||
|
||||
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va)
|
||||
{
|
||||
return _vsnprintf(_out_buffer, buffer, count, format, va);
|
||||
}
|
||||
|
||||
|
||||
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
const out_fct_wrap_type out_fct_wrap = { out, arg };
|
||||
const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
121
arm9/source/printf.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// \author (c) Marco Paland (info@paland.com)
|
||||
// 2014-2019, PALANDesign Hannover, Germany
|
||||
//
|
||||
// \license The MIT License (MIT)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
|
||||
// embedded systems with a very limited resources.
|
||||
// Use this instead of bloated standard/newlib printf.
|
||||
// These routines are thread safe and reentrant.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _PRINTF_H_
|
||||
#define _PRINTF_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PRINTF_DISABLE_SUPPORT_FLOAT
|
||||
#define PRINTF_DISABLE_SUPPORT_EXPONENTIAL
|
||||
#define PRINTF_DISABLE_SUPPORT_LONG_LONG
|
||||
#define PRINTF_DISABLE_SUPPORT_PTRDIFF_T
|
||||
|
||||
/**
|
||||
* Output a character to a custom device like UART, used by the printf() function
|
||||
* This function is declared here only. You have to write your custom implementation somewhere
|
||||
* \param character Character to output
|
||||
*/
|
||||
void _putchar(char character);
|
||||
|
||||
|
||||
/**
|
||||
* Tiny printf implementation
|
||||
* You have to implement _putchar if you use printf()
|
||||
* To avoid conflicts with the regular printf() API it is overridden by macro defines
|
||||
* and internal underscore-appended functions like printf_() are used
|
||||
* \param format A string that specifies the format of the output
|
||||
* \return The number of characters that are written into the array, not counting the terminating null character
|
||||
*/
|
||||
#define printf printf_
|
||||
int printf_(const char* format, ...);
|
||||
|
||||
|
||||
/**
|
||||
* Tiny sprintf implementation
|
||||
* Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!
|
||||
* \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output!
|
||||
* \param format A string that specifies the format of the output
|
||||
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
|
||||
*/
|
||||
#define sprintf sprintf_
|
||||
int sprintf_(char* buffer, const char* format, ...);
|
||||
|
||||
|
||||
/**
|
||||
* Tiny snprintf/vsnprintf implementation
|
||||
* \param buffer A pointer to the buffer where to store the formatted string
|
||||
* \param count The maximum number of characters to store in the buffer, including a terminating null character
|
||||
* \param format A string that specifies the format of the output
|
||||
* \param va A value identifying a variable arguments list
|
||||
* \return The number of characters that COULD have been written into the buffer, not counting the terminating
|
||||
* null character. A value equal or larger than count indicates truncation. Only when the returned value
|
||||
* is non-negative and less than count, the string has been completely written.
|
||||
*/
|
||||
#define snprintf snprintf_
|
||||
#define vsnprintf vsnprintf_
|
||||
int snprintf_(char* buffer, size_t count, const char* format, ...);
|
||||
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va);
|
||||
|
||||
|
||||
/**
|
||||
* Tiny vprintf implementation
|
||||
* \param format A string that specifies the format of the output
|
||||
* \param va A value identifying a variable arguments list
|
||||
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
|
||||
*/
|
||||
#define vprintf vprintf_
|
||||
int vprintf_(const char* format, va_list va);
|
||||
|
||||
|
||||
/**
|
||||
* printf with output function
|
||||
* You may use this as dynamic alternative to printf() with its fixed _putchar() output
|
||||
* \param out An output function which takes one character and an argument pointer
|
||||
* \param arg An argument pointer for user data passed to output function
|
||||
* \param format A string that specifies the format of the output
|
||||
* \return The number of characters that are sent to the output function, not counting the terminating null character
|
||||
*/
|
||||
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _PRINTF_H_
|
6
arm9/source/soundbank.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#define SFX_CLICKNOQUIT 0
|
||||
#define SFX_KEYCLICK 1
|
||||
#define SFX_MUS_INTRO 2
|
||||
#define MSL_NSONGS 0
|
||||
#define MSL_NSAMPS 3
|
||||
#define MSL_BANKSIZE 3
|
BIN
logo.bmp
Before Width: | Height: | Size: 630 B After Width: | Height: | Size: 630 B |
250
readme.txt
|
@ -1,250 +0,0 @@
|
|||
a7800DS
|
||||
--------------------------------------------------------------------------------
|
||||
a7800DS is an Atari ProSystem 7800 console emulator.
|
||||
To use this emulator, you must use compatibles rom with a78/bin format.
|
||||
Strongly recommend you use NTSC roms... PAL ones have more scanlines and will render
|
||||
more slowly and since the sound core is tied to scanlines, the sound will be wrong.
|
||||
All the debug on this port to the DS has been done with NTSC roms - seek them out!
|
||||
Do not ask me about such files, I don't have them. A search with Google will certainly
|
||||
help you.
|
||||
|
||||
Features :
|
||||
----------
|
||||
Most things you should expect from an emulator. Speed is good. Sound is good except
|
||||
for the few games that run below 60FPS.
|
||||
|
||||
Philosophy :
|
||||
----------
|
||||
I'm not striving for emulation accuracy - the goal is to get as many games as close
|
||||
to perfectly playable as possible. Nothing else matters if the game won't run at
|
||||
near full speed with all the gameplay in-tact. Minor screen glitches or minor sound
|
||||
issues are secondary to making sure the game will actually run. If you're looking
|
||||
for a highly accurate emulator for the 7800 ProSystem, this isn't it - try MAME/MESS.
|
||||
But if you're looking to enjoy some classic console goodness on your DS/DSi then
|
||||
you've come to the right place!
|
||||
|
||||
Be warned, the emulation of the ProSystem is tricky as there are several CPU-like
|
||||
elments that need to be emulated (6502, TIA, RIOT, Pokey Chip) and the DS-LITE
|
||||
just doesn't have the horsepower to do it properly so only the smallest non-Pokey
|
||||
games will run (Asteroids, Centipede, Joust, Meteor Shower, Moon Cresta, Ms Pac Man).
|
||||
The DSi will run most games at near full speed or beyond - with much higher emulation
|
||||
compatibility.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
History :
|
||||
--------------------------------------------------------------------------------
|
||||
V2.6 : 02-Apr-2021 by wavemotion-dave
|
||||
* Faster directory/file listing.
|
||||
* Support for the latest homebrews: Galaxian and Popeye
|
||||
* Improved scaling and offset handling using L/R + Arrow Keys to match other emulators.
|
||||
|
||||
V2.5 : 15-Jan-2021 by wavemotion-dave
|
||||
* Added .A78 header naming search and as a backup filename search to help
|
||||
properly identify the game being loaded so that the right settings can be applied.
|
||||
|
||||
V2.4 : 8-Jan-2021 by wavemotion-dave
|
||||
* Improvement in bank switching allowing most games to run 60FPS.
|
||||
|
||||
V2.3 : 6-Jan-2021 by wavemotion-dave
|
||||
* Fixed large cart support so 512kb games run fine.
|
||||
* Fixed voice in Frenzy/Berzerk.
|
||||
* Fixed graphical glitches in Alien Brigade.
|
||||
* Optmized bank switching so more big games run smoothly.
|
||||
* Added default difficulty switches for the few games that need them.
|
||||
* Lots of cleanups as time permitted.
|
||||
|
||||
V2.2 : 5-Jan-2021 by wavemotion-dave
|
||||
* More memory tweaks - faster processing of memory for another 5% speedup.
|
||||
|
||||
V2.1 : 3-Jan-2021 by wavemotion-dave
|
||||
* Now using DTCM and VRAM for some key memory areas to speed up the emulator almost 10%
|
||||
|
||||
V2.0 : 1-Jan-2021 by wavemotion-dave
|
||||
* Pokey and TIA sound core reworked to provide sound that is worth listening to.
|
||||
* Please run on a DSi, DSi-XL/LL or 3DS. You won't be happy with the performance on a DS-LITE/PHAT.
|
||||
|
||||
V1.9 : 31-Dec-2020 by wavemotion-dave
|
||||
* Robotron now works with with Twin-Sticks!
|
||||
* Minor cleanup and polish to end the year...
|
||||
|
||||
V1.8 : 23-Dec-2020 by wavemotion-dave
|
||||
* Major improvements to CPU core to get about 10% speed boost across the board.
|
||||
More games playable at full speed on DSi and above. Special DS-LITE build
|
||||
included that supports only the smallest and most basic games (but at near
|
||||
full speed).
|
||||
|
||||
V1.7a : 21-Dec-2020 by wavemotion-dave
|
||||
* Full Pokey Support at both 450 and 4000. XM RAM mapping at 4000 so games
|
||||
like Serpentine will run properly now. Undocumented opcodes for the Sally
|
||||
processor now implemented so games like Popeye will run fine.
|
||||
|
||||
V1.7 : 20-Dec-2020 by wavemotion-dave
|
||||
* After much thought and debug, I've ditched Kangaroo mode. As near as I can
|
||||
tell it's used on only a couple of games and not for gameplay - and it costs
|
||||
more DS-CPU time than it's worth. There is no harm other than a potential
|
||||
graphical glitch which I've not noticed and that CPU time is precious.
|
||||
|
||||
V1.6b : 19-Dec-2020 by wavemotion-dave
|
||||
* Fixed bug causing black rectangles on some games - thanks to Wii-7800!
|
||||
|
||||
V1.6 : 17-Dec-2020 by wavemotion-dave
|
||||
* Minor cleanup. Rebranding to PHOENIX EDITION.
|
||||
|
||||
V1.5 : 15-Dec-2020 by wavemotion-dave
|
||||
* Overhaul of scaling and X/Y offsets so that more games look pixel perfect.
|
||||
* More homebrews run... compatibility table added to the back end of this doc.
|
||||
* More robust handling of High Score Cart and saving of files.
|
||||
|
||||
V1.4 : 13-Dec-2020 by wavemotion-dave
|
||||
* Implemented Hiscore Saving per the HSC cart. Put the 4k highscore.rom (don't ask)
|
||||
where your ROMs live. If found, it will enable saving of high scores
|
||||
on all 9 original games (Asteroids, Joust, Centipede, Xevious, Dig Dug, Galaga,
|
||||
Food Fight, Ms Pac-Man and Robotron) as well as most of the newer homebrews.
|
||||
|
||||
V1.3 : 12-Dec-2020 by wavemotion-dave
|
||||
* Backported some fixes and emulation timing improvments from Prosystem 1.3g
|
||||
plus the Wii version. Renders a few more games playable.
|
||||
* Fixed region for Froggie and Beef Drop - they now look right and play
|
||||
at full speed.
|
||||
* Minor other improvements as time permitted.
|
||||
|
||||
V1.2 : 10-Dec-2020 by wavemotion-dave
|
||||
* More speed improvements. Fixed some 320 pixel games. Improved sound.
|
||||
|
||||
V1.1 : 09-Dec-2020 by wavemotion-dave
|
||||
* Brought back to life... cleanup and about a 50% speed improvement, better
|
||||
screen rendering/scaling and slightly improved UI features.
|
||||
|
||||
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/
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
How tu use a7800DS :
|
||||
--------------------------------------------------------------------------------
|
||||
Place .NDS on your SD card and launch with Twilight Menu++ or Unlaunch.
|
||||
If you want to run on a flash cart, it might work... recommend HBMENU to launch.
|
||||
Strongly recommend you run on a DSi or 3DS to get full speed. DS-LITE/PHAT is slow.
|
||||
|
||||
When the emulator starts, click on the cartridge slot to choose a file. Use Up/Down
|
||||
to select a file, then use A to load it.
|
||||
|
||||
Controls :
|
||||
* Direction pad : the joystick ...
|
||||
* A : Fire button 1
|
||||
* B : Fire button 2
|
||||
* SELECT : SELECT Button
|
||||
* START : PAUSE Button
|
||||
* X : FPS Display
|
||||
* Y : Fire Button 1 (for those that prefer not using A)
|
||||
* L/R + DPAD : Used to Shift Offsets and Scale Screen to desired ratio
|
||||
|
||||
Use stylus on buttons for other actions on bottom screen.
|
||||
|
||||
High Score Saving works if you have highscore.rom (exact name and case) in your
|
||||
roms directory where you load your games... also, you MUST press the HSC button
|
||||
if you want to snap the Saved Scores out to the flash card. It's not something
|
||||
I want to do as the game runs... so you must do it... the high scores will also
|
||||
auto-save if you quit the emulator or select a new game.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
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).
|
||||
raz0red (http://www.twitchasylum.com/forum/viewtopic.php?t=519) for WII7800 (that
|
||||
helped me a lot to fix some timing problem).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Original Author:
|
||||
Alekmaul
|
||||
alekmaul@portabledev.com
|
||||
http://www.portabledev.com
|
||||
|
||||
Updates by wavemotion-dave: https://github.com/wavemotion-dave/A7800DS
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Compatibility Table
|
||||
|
||||
GAME MD5SUM HSC FPS NOTES
|
||||
========================================================================================================================
|
||||
Ace Of Aces 0be996d25144966d5541c9eb4919b289 NO 60 Minor graphical glitches. Very playable.
|
||||
Alien Brigade 877dcc97a775ed55081864b2dbf5f1e2 NO 52 A bit slow but playable
|
||||
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 Minor glitches. Mostly playable.
|
||||
Beef Drop (Final) 78b1061d651ef806becac1dd3fda29a0 YES 60 Near perfect.
|
||||
BonQ (Final) 9fa7743a016c9b7015ee1d386326f88e YES 60 Graphical glitches on title screen. Play is 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 Glitchy top graphics... but playable.
|
||||
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 (voice slightly wrong pitch)
|
||||
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. What's the point of this game?!
|
||||
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 044657294450c869c45e7ef61f4870de YES 60 Near perfect
|
||||
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 bfad016d6e77eaccec74c0340aded8b9 NO 50 A bit slow but playable
|
||||
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
|
||||
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
|
||||
|
||||
|
BIN
techdocs/HSC-7800.png
Normal file
After Width: | Height: | Size: 424 KiB |
192
techdocs/a78header.asm
Normal file
|
@ -0,0 +1,192 @@
|
|||
; A78 Header v4.2
|
||||
;
|
||||
; Use this file to add an a78 header via the source code of your ROM.
|
||||
;
|
||||
; _Implementation Notes_
|
||||
;
|
||||
; * Include this header near the beginning of your DASM source, but after
|
||||
; your initial ROM ORG statement.
|
||||
; * Change the fields withn the file to describe your game's hardware
|
||||
; requirements to emulators and flash carts.
|
||||
; * All unused/reserved bits and bytes must be set to zero.
|
||||
|
||||
.ROMSIZE = $20000 ; Update with your total ROM size.
|
||||
|
||||
; Uncomment the following entry to force older v3 style headers.
|
||||
;V3ONLY = 1
|
||||
|
||||
; Uncomment the following entry to break support with platforms that only
|
||||
; have v3 headers implemented.
|
||||
;V4ONLY = 1
|
||||
|
||||
; Auto-header ROM allocation follows. If the current address is page aligned,
|
||||
; we backup 128 bytes. This may cause issues if you use a different ORG+RORG
|
||||
; at the start of your ROM - in that case, account for the 128 bytes of
|
||||
; header within your game ROM start ORG+RORG statements.
|
||||
|
||||
if ( . & $FF ) = 0 ; Check if we're at an even page.
|
||||
ORG (. - 128),0 ; If so, go -128 bytes, for header space.
|
||||
else
|
||||
ORG .,0 ; In case zero-fill wasn't specified
|
||||
endif ; orginally.
|
||||
|
||||
SEG ROM
|
||||
|
||||
.HEADER = .
|
||||
|
||||
; Format detection - do not modify.
|
||||
#ifconst V3ONLY
|
||||
DC.B 3 ; 0 header major version
|
||||
#else
|
||||
DC.B 4 ; 0 header major version
|
||||
#endif ; V3ONLY
|
||||
DC.B "ATARI7800" ; 1..16 header magic string - zero pad
|
||||
|
||||
|
||||
ORG .HEADER+$11,0
|
||||
DC.B "Game Name Here" ; 17..48 cartridge title string - zero pad
|
||||
|
||||
|
||||
ORG .HEADER+$31,0
|
||||
DC.B (.ROMSIZE>>24) ; 49..52 cartridge ROM size
|
||||
DC.B (.ROMSIZE>>16&$FF)
|
||||
DC.B (.ROMSIZE>>8&$FF)
|
||||
DC.B (.ROMSIZE&$FF)
|
||||
|
||||
#ifnconst V4ONLY
|
||||
|
||||
; The following 2 cartridge type bytes are deprecated as of header v4.0.
|
||||
; It's recommended that you still populate these bytes for support with
|
||||
; platforms that don't yet support v4.
|
||||
|
||||
DC.B %00000000 ; 53 cartridge type A
|
||||
DC.B %00000000 ; 54 cartridge type B
|
||||
; _Cartridge Type A_
|
||||
; bit 7 ; POKEY @ $0800 - $080F
|
||||
; bit 6 ; EXRAM/M2 (halt banked RAM)
|
||||
; bit 5 ; BANKSET
|
||||
; bit 4 ; SOUPER
|
||||
; bit 3 ; YM2151 @ $0460 - $0461
|
||||
; bit 2 ; POKEY @ $0440 - $044F
|
||||
; bit 1 ; ABSOLUTE
|
||||
; bit 0 ; ACTIVISION
|
||||
; _Cartridge Type B_
|
||||
; bit 7 ; EXRAM/A8 (mirror RAM)
|
||||
; bit 6 ; POKEY @ $0450 - $045F
|
||||
; bit 5 ; EXRAM/X2 (hotspot banked RAM)
|
||||
; bit 4 ; EXFIX (2nd last bank @ $4000)
|
||||
; bit 3 ; EXROM (ROM @ $4000)
|
||||
; bit 2 ; EXRAM (RAM @ $4000)
|
||||
; bit 1 ; SUPERGAME
|
||||
; bit 0 ; POKEY @ $4000 - $7FFF
|
||||
|
||||
#else
|
||||
DC.B %11111111
|
||||
DC.B %11111111
|
||||
#endif ; !V4ONLY
|
||||
|
||||
DC.B 1 ; 55 controller 1 device type
|
||||
DC.B 1 ; 56 controller 2 device type
|
||||
; 0 = none
|
||||
; 1 = 7800 joystick
|
||||
; 2 = lightgun
|
||||
; 3 = paddle
|
||||
; 4 = trakball
|
||||
; 5 = 2600 joystick
|
||||
; 6 = 2600 driving
|
||||
; 7 = 2600 keypad
|
||||
; 8 = ST mouse
|
||||
; 9 = Amiga mouse
|
||||
; 10 = AtariVox
|
||||
; 11 = SNES2Atari
|
||||
; 12 = Mega7800
|
||||
|
||||
|
||||
DC.B %00000000 ; 57 tv type
|
||||
; bits 7..3 ; reserved
|
||||
; bit 2 ; 0:single-region,1:multi-region
|
||||
; bit 1 ; 0:component,1:composite
|
||||
; bit 0 ; 0:NTSC,1:PAL
|
||||
|
||||
|
||||
DC.B %00000000 ; 58 save peripheral
|
||||
; bits 7..2 ; reserved
|
||||
; bit 1 ; SaveKey/AtariVox
|
||||
; bit 0 ; High Score Cart (HSC)
|
||||
|
||||
|
||||
; The following irq source byte is deprecated as of header v4.0.
|
||||
; It's recommended that you still populate this byte for support with
|
||||
; platforms that don't yet support v4.
|
||||
|
||||
ORG .HEADER+62,0
|
||||
DC.B %00000000 ; 62 external irq source
|
||||
; bits 7..5 ; reserved
|
||||
; bit 4 ; POKEY @ $0800 - $080F
|
||||
; bit 3 ; YM2151 @ $0460 - $0461
|
||||
; bit 2 ; POKEY @ $0440 - $044F
|
||||
; bit 1 ; POKEY @ $0450 - $045F
|
||||
; bit 0 ; POKEY @ $4000 - $7FFF
|
||||
|
||||
DC.B %00000000 ; 63 slot passthrough device
|
||||
; bits 7..1 ; reserved
|
||||
; bit 0 ; XM module
|
||||
|
||||
#ifnconst V3ONLY
|
||||
|
||||
; The following 6 bytes are v4 header specific. You should populate
|
||||
; them with valid info if you're not using V3ONLY, because they will
|
||||
; take precedence over v3 headers.
|
||||
|
||||
DC.B 0 ; 64 mapper
|
||||
; 0 = linear
|
||||
; 1 = supergame
|
||||
; 2 = activision
|
||||
; 3 = absolute
|
||||
; 4 = souper
|
||||
|
||||
|
||||
DC.B 0 ; 65 mapper options
|
||||
; linear_
|
||||
; bit 7 ; bankset rom
|
||||
; bits 0-1 ; option @4000...
|
||||
; 0 = none
|
||||
; 1 = 16K EXRAM
|
||||
; 2 = 8K EXRAM/A8
|
||||
; 3 = 32K EXRAM/M2
|
||||
; supergame_
|
||||
; bit 7 ; bankset rom
|
||||
; bits 0-2 ; option @4000...
|
||||
; 0 = none
|
||||
; 1 = 16K EXRAM
|
||||
; 2 = 8K EXRAM/A8
|
||||
; 3 = 32K EXRAM/M2
|
||||
; 4 = 16K EXROM
|
||||
; 5 = EXFIX
|
||||
; 6 = 32K EXRAM/X2
|
||||
|
||||
DC.B %00000000 ; 66 audio hi
|
||||
DC.B %00000000 ; 67 audio lo
|
||||
; bit 5 ; adpcm@420
|
||||
; bit 4 ; covox@430
|
||||
; bit 3 ; ym2151@460
|
||||
; bits 0-2 ; pokey...
|
||||
; 0 = none
|
||||
; 1 = pokey@440
|
||||
; 2 = pokey@450
|
||||
; 3 = dual pokey @440+@450
|
||||
; 4 = pokey@800
|
||||
; 5 = pokey@4000
|
||||
|
||||
DC.B %00000000 ; 68 interrupt hi
|
||||
DC.B %00000000 ; 69 interrupt lo
|
||||
; bit 2 ; YM2151
|
||||
; bit 1 ; pokey 2 (@440)
|
||||
; bit 0 ; pokey 1 (@4000, @450, or @800)
|
||||
|
||||
#endif ; !V3ONLY
|
||||
|
||||
|
||||
ORG .HEADER+100,0 ; 100..127 footer magic string
|
||||
DC.B "ACTUAL CART DATA STARTS HERE"
|
||||
|