Compare commits
No commits in common. "main" and "1.4" have entirely different histories.
BIN
A7800DS.nds
1
A7800DS.pnproj
Normal file
|
@ -0,0 +1 @@
|
|||
<Project name="A7800DS"><Folder name="arm7"><File path="arm7\Makefile"></File><File path="arm7\source\main.c"></File><File path="arm7\source\emusoundfifo.c"></File></Folder><Folder name="arm9"><Folder name="emu"><Folder name="zip"><File path="arm9\source\emu\zip\ioapi.c"></File><File path="arm9\source\emu\zip\ioapi.h"></File><File path="arm9\source\emu\zip\miniunz.c"></File><File path="arm9\source\emu\zip\miniunz.h"></File><File path="arm9\source\emu\zip\unzip.c"></File><File path="arm9\source\emu\zip\unzip.h"></File><File path="arm9\source\emu\zip\zip.c"></File><File path="arm9\source\emu\zip\zip.h"></File></Folder><File path="arm9\source\emu\Archive.c"></File><File path="arm9\source\emu\Archive.h"></File><File path="arm9\source\emu\Bios.c"></File><File path="arm9\source\emu\Bios.h"></File><File path="arm9\source\emu\Cartridge.c"></File><File path="arm9\source\emu\Cartridge.h"></File><File path="arm9\source\emu\Database.c"></File><File path="arm9\source\emu\Database.h"></File><File path="arm9\source\emu\Equates.h"></File><File path="arm9\source\emu\Hash.c"></File><File path="arm9\source\emu\Hash.h"></File><File path="arm9\source\emu\Logger.c"></File><File path="arm9\source\emu\Logger.h"></File><File path="arm9\source\emu\Maria.h"></File><File path="arm9\source\emu\Memory.c"></File><File path="arm9\source\emu\Memory.h"></File><File path="arm9\source\emu\Pair.h"></File><File path="arm9\source\emu\Palette.c"></File><File path="arm9\source\emu\Palette.h"></File><File path="arm9\source\emu\Pokey.c"></File><File path="arm9\source\emu\Pokey.h"></File><File path="arm9\source\emu\ProSystem.h"></File><File path="arm9\source\emu\Rect.h"></File><File path="arm9\source\emu\Region.c"></File><File path="arm9\source\emu\Region.h"></File><File path="arm9\source\emu\Riot.c"></File><File path="arm9\source\emu\Riot.h"></File><File path="arm9\source\emu\Sally.h"></File><File path="arm9\source\emu\shared.h"></File><File path="arm9\source\emu\Sound.c"></File><File path="arm9\source\emu\Sound.h"></File><File path="arm9\source\emu\Tia.h"></File><File path="arm9\source\emu\Sally.itcm.c"></File><File path="arm9\source\emu\ProSystem.c"></File><File path="arm9\source\emu\Maria.c"></File><File path="arm9\source\emu\Tia.itcm.c"></File></Folder><Folder name="Fst6502"><File path="arm9\source\emu\Fst6502\Fst6502.h"></File><File path="arm9\source\emu\Fst6502\Fst6502.s"></File><File path="arm9\source\emu\Fst6502\Fst6502_interface.c"></File><File path="arm9\source\emu\Fst6502\Fst6502_interface.h"></File></Folder><File path="arm9\Makefile"></File><File path="arm9\source\main.c"></File><File path="arm9\source\a7800utils.h"></File><File path="arm9\source\a7800utils.c"></File><File path="arm9\source\intro.h"></File><File path="arm9\source\intro.c"></File></Folder><File path="readme.txt"></File><File path="Makefile"></File></Project>
|
4
Makefile
|
@ -1,4 +1,4 @@
|
|||
VERSION=5.1
|
||||
VERSION=1.4
|
||||
TARGNAME=A7800DS
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
|
@ -13,7 +13,7 @@ include $(DEVKITARM)/ds_rules
|
|||
export TARGET := $(shell basename $(TARGNAME))
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
ICON := -b $(CURDIR)/logo.bmp "A7800DS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/A7800DS"
|
||||
ICON := -b $(CURDIR)/logo.bmp "A7800DS $(VERSION);AlekMaul;http://www.portabledev.com"
|
||||
|
||||
.PHONY: arm7/$(TARGET).elf arm9/$(TARGET).elf
|
||||
|
||||
|
|
432
README.md
|
@ -1,432 +0,0 @@
|
|||
# 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 -O2\
|
||||
CFLAGS := -g -Wall -O3\
|
||||
-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 -lmm7
|
||||
LIBS := -ldswifi7 -lnds7 -lmm7
|
||||
#LIBS := -ldswifi7 -lmm7 -lnds7
|
||||
LIBS := -ldswifi7 -lnds7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
|
|
@ -9,8 +9,7 @@ typedef enum {
|
|||
} FifoMesType;
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void soundEmuDataHandler(int bytes, void *user_data)
|
||||
{
|
||||
void soundEmuDataHandler(int bytes, void *user_data) {
|
||||
int channel = -1;
|
||||
|
||||
FifoMessage msg;
|
||||
|
@ -41,8 +40,7 @@ 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;
|
||||
|
@ -77,8 +75,7 @@ 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,7 +32,6 @@
|
|||
#include <maxmod7.h>
|
||||
|
||||
extern void installSoundEmuFIFO(void);
|
||||
extern void mmInstall( int fifo_channel );
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void VblankHandler(void) {
|
||||
|
@ -55,10 +54,9 @@ void powerButtonCB() {
|
|||
exitflag = true;
|
||||
}
|
||||
|
||||
void mmInstall(int);
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
int main() {
|
||||
//---------------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------------
|
||||
readUserSettings();
|
||||
|
||||
|
@ -68,7 +66,7 @@ int main() {
|
|||
touchInit();
|
||||
fifoInit();
|
||||
|
||||
mmInstall( FIFO_MAXMOD );
|
||||
//mmInstall(FIFO_MAXMOD);
|
||||
|
||||
SetYtrigger(80);
|
||||
|
||||
|
@ -77,10 +75,12 @@ int main() {
|
|||
|
||||
installSystemFIFO();
|
||||
|
||||
irqSet(IRQ_VCOUNT, VcountHandler);
|
||||
irqSet(IRQ_VBLANK, VblankHandler);
|
||||
installSoundEmuFIFO();
|
||||
|
||||
irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK);
|
||||
irqSet(IRQ_VCOUNT, VcountHandler);
|
||||
//irqSet(IRQ_VBLANK, VblankHandler);
|
||||
|
||||
irqEnable( 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,19 +26,22 @@ 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 := $(ARCH) -march=armv5te -mtune=arm946e-s
|
||||
#ASFLAGS := -g $(ARCH) -march=armv5te -mtune=arm946e-s
|
||||
ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s
|
||||
|
||||
LDFLAGS = -specs=ds_arm9.specs $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
#LDFLAGS = -specs=ds_arm9.specs -g $(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 -lmm9
|
||||
LIBS := -lfat -lnds9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
@ -53,7 +56,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)) \
|
||||
|
@ -120,8 +123,13 @@ $(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)
|
||||
|
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 2.3 KiB |
|
@ -1,29 +1,3 @@
|
|||
// =====================================================================================
|
||||
// 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
|
||||
|
||||
|
@ -33,7 +7,7 @@
|
|||
#define A7800_PLAYGAME 0x04
|
||||
#define A7800_QUITSTDS 0x05
|
||||
|
||||
extern short int emu_state;
|
||||
extern int etatEmu;
|
||||
|
||||
typedef enum {
|
||||
EMUARM7_INIT_SND = 0x123C,
|
||||
|
@ -43,13 +17,14 @@ typedef enum {
|
|||
|
||||
typedef struct FICtoLoad {
|
||||
char filename[255];
|
||||
u8 directory;
|
||||
bool directory;
|
||||
unsigned int uCrc;
|
||||
} FICA7800;
|
||||
|
||||
typedef struct {
|
||||
unsigned int sndLevel;
|
||||
unsigned int m_ScreenRatio; // 0 = original show, 1 = full screen
|
||||
unsigned short DS_Pad[16]; // each key mapping
|
||||
unsigned short DS_Pad[12]; // each key mapping
|
||||
unsigned int m_DisplayFPS;
|
||||
} gamecfg;
|
||||
|
||||
|
@ -57,14 +32,20 @@ typedef struct {
|
|||
|
||||
extern gamecfg GameConf;
|
||||
|
||||
extern uint video_height; // Actual video height
|
||||
extern unsigned short *bufVideo; // Video buffer
|
||||
extern unsigned int gameCRC; // crc checksum of file
|
||||
|
||||
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(bool);
|
||||
extern void dsShowScreenMain(void);
|
||||
extern void dsFreeEmu(void);
|
||||
extern void VsoundHandler(void);
|
||||
extern void dsLoadGame(char *filename);
|
||||
|
|
|
@ -1,389 +0,0 @@
|
|||
// =====================================================================================
|
||||
// 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
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
// =====================================================================================
|
||||
// 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
|
172
arm9/source/emu/Archive.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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) {
|
||||
#if 0
|
||||
if(strlen(filename) == 0) {
|
||||
logger_LogError("Zip filename is invalid.", ARCHIVE_SOURCE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unzFile file = unzOpen(filename);
|
||||
if(file == NULL) {
|
||||
logger_LogInfo("Filename " + filename + " is not a valid zip file.", ARCHIVE_SOURCE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = unzGoToFirstFile(file);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to find the first file within the zip file.", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unz_file_info_s zipInfo = {0};
|
||||
char buffer[_MAX_PATH] = {0};
|
||||
result = unzGetCurrentFileInfo(file, &zipInfo, buffer, _MAX_PATH, NULL, 0, NULL, 0);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to retrieve the current zipped file info.", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint size = zipInfo.uncompressed_size;
|
||||
unzClose(file);
|
||||
return size;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Uncompress
|
||||
// ----------------------------------------------------------------------------
|
||||
bool archive_Uncompress(char* filename, byte* data, uint size) {
|
||||
#if 0
|
||||
if(strlen(filename) == 0) {
|
||||
logger_LogError("Zip filename is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
if(data == NULL) {
|
||||
logger_LogError("Data parameter is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
unzFile file = unzOpen(filename);
|
||||
if(file == NULL) {
|
||||
logger_LogInfo("Filename " + filename + " is not a valid zip file.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = unzGoToFirstFile(file);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to find the first file within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = unzOpenCurrentFile(file);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to open the first file within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = unzReadCurrentFile(file, data, size);
|
||||
if(result != size) {
|
||||
logger_LogInfo("Failed to read first file data within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzCloseCurrentFile(file);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
unzCloseCurrentFile(file);
|
||||
unzClose(file);
|
||||
return true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Compress
|
||||
// ----------------------------------------------------------------------------
|
||||
bool archive_Compress(char* zipFilename, char* filename, const byte* data, uint size) {
|
||||
#if 0
|
||||
if(strlen(zipFilename) == 0) {
|
||||
logger_LogError("Zip filename is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
if(strlen(filename) == 0) {
|
||||
logger_LogError("Filename is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
if(data == NULL) {
|
||||
logger_LogError("Data parameter is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
zipFile file = zipOpen(zipFilename, APPEND_STATUS_CREATE);
|
||||
if(file == NULL) {
|
||||
logger_LogInfo("Failed to create the zip file " + zipFilename + ".", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
zip_fileinfo fileInfo = {0};
|
||||
fileInfo.dosDate = 1;
|
||||
|
||||
int result = zipOpenNewFileInZip(file, filename, &fileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION);
|
||||
if(result != ZIP_OK) {
|
||||
logger_LogInfo("Failed to open a new file within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
zipClose(file, "Failed to compress.");
|
||||
return false;
|
||||
}
|
||||
|
||||
result = zipWriteInFileInZip(file, data, size);
|
||||
if(result != ZIP_OK) {
|
||||
logger_LogInfo("Failed to write data to the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
zipCloseFileInZip(file);
|
||||
zipClose(file, "Failed to compress.");
|
||||
return false;
|
||||
}
|
||||
|
||||
zipCloseFileInZip(file);
|
||||
zipClose(file, "Comment");
|
||||
return true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
40
arm9/source/emu/Archive.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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
|
126
arm9/source/emu/Bios.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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) {
|
||||
#if 0
|
||||
logger_LogError("Bios filename is invalid.", BIOS_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bios_Release( );
|
||||
#if 0
|
||||
logger_LogInfo("Opening bios file " + filename + ".");
|
||||
#endif
|
||||
|
||||
bios_size = archive_GetUncompressedFileSize(filename);
|
||||
if(bios_size == 0) {
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
#if 0
|
||||
logger_LogError("Failed to open the bios file " + filename + " for reading.", BIOS_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
#if 0
|
||||
if(fseek(file, 0, SEEK_END)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the end of the bios file.", BIOS_SOURCE);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bios_size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
#if 0
|
||||
if(fseek(file, 0, SEEK_SET)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the size of the bios file.", BIOS_SOURCE);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bios_data = (byte *) malloc(bios_size);
|
||||
fread(bios_data, 1, bios_size, file);
|
||||
#if 0
|
||||
if(fread(bios_data, 1, bios_size, file) != bios_size && ferror(file)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to read the bios data.", BIOS_SOURCE);
|
||||
bios_Release( );
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -20,23 +20,23 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// HighScore.h
|
||||
// Bios.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef HIGHSCORE_H
|
||||
#define HIGHSCORE_H
|
||||
#ifndef BIOS_H
|
||||
#define BIOS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "Equates.h"
|
||||
#include "Memory.h"
|
||||
#include "Hash.h"
|
||||
#include "Pokey.h"
|
||||
#include "Archive.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
extern bool cartridge_LoadHighScoreCart(void);
|
||||
extern bool cartridge_SaveHighScoreSram(void);
|
||||
|
||||
extern byte high_score_cart_loaded;
|
||||
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
|
|
@ -24,98 +24,57 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#ifndef CARTRIDGE_H
|
||||
#define CARTRIDGE_H
|
||||
#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_WSYNC_MASK 2
|
||||
#define CARTRIDGE_CYCLE_STEALING_MASK 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#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_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 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 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];
|
||||
extern bool cartridge_LoadHighScoreCart();
|
||||
extern bool cartridge_SaveHighScoreSram();
|
||||
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 bool cartridge_pokey;
|
||||
extern bool cartridge_pokey450;
|
||||
extern bool cartridge_hsc_enabled;
|
||||
extern byte cartridge_controller[2];
|
||||
extern byte cartridge_bank;
|
||||
extern uint cartridge_flags;
|
||||
extern int cartridge_yOffset;
|
||||
extern int cartridge_xOffset;
|
||||
|
||||
extern bool cartridge_wsync;
|
||||
extern bool cartridge_cycle_stealing;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,471 +22,206 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Database.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include <ctype.h>
|
||||
|
||||
#include "Database.h"
|
||||
#include "ProSystem.h"
|
||||
#include "../config.h"
|
||||
|
||||
Database_Entry myCartInfo __attribute__((section(".dtcm")));
|
||||
extern uint cartridge_size;
|
||||
#define DATABASE_SOURCE "Database.cpp"
|
||||
|
||||
// To get the md5sum of an .a78 file with header in Linux: dd bs=1 skip=128 if=somefile.a78 | md5sum
|
||||
bool database_enabled = true;
|
||||
typedef struct {
|
||||
char digest[33];
|
||||
uint cardtype;
|
||||
bool pokey;
|
||||
uint cardctrl1;
|
||||
uint cardctrl2;
|
||||
uint cardregion;
|
||||
uint cardflags;
|
||||
bool hsc;
|
||||
int yOffset;
|
||||
} Database_Entry;
|
||||
|
||||
Database_Entry game_list[] = {
|
||||
|
||||
// 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
|
||||
{"4332c24e4f3bc72e7fe1b77adf66c2b7",0,false,1,1,0,0, false, 22}, // title=3D Asteroids
|
||||
{"0be996d25144966d5541c9eb4919b289",4,false,1,1,0,0, false, 22}, // title=Ace Of Aces
|
||||
{"aadde920b3aaba03bc10b40bd0619c94",4,false,1,1,1,0, false, 22}, // title=Ace Of Aces
|
||||
{"877dcc97a775ed55081864b2dbf5f1e2",2,false,3,3,0,0, false, 22}, // title=Alien Brigade
|
||||
{"de3e9496cb7341f865f27e5a72c7f2f5",2,false,3,3,1,0, false, 22}, // title=Alien Brigade
|
||||
{"07342c78619ba6ffcc61c10e907e3b50",0,false,1,1,0,0, true, 25}, // title=Asteroids
|
||||
{"a65f79ad4a0bbdecd59d5f7eb3623fd7",0,false,1,1,0,0, true, 22}, // title=Asteroids Deluxe
|
||||
{"3d38281ed8a8d8c7cd457a18c92c8604",0,false,1,1,0,0, true, 21}, // title=Astro Blaster
|
||||
{"a51e5df28a0fe8c52e9d28fb5f8e44a6",0,false,1,1,0,0, true, 21}, // title=Astro Fighter
|
||||
{"7cdfbe37634e7dcd4dc67db7edbcd3ba",0,false,1,1,0,0, false, 22}, // title=Baby Pac Man
|
||||
{"8fc3a695eaea3984912d98ed4a543376",0,true ,1,1,0,0, false, 22}, // title=Ballblazer
|
||||
{"b558814d54904ce0582e2f6a801d03af",0,true ,1,1,1,0, false, 22}, // title=Ballblazer
|
||||
{"42682415906c21c6af80e4198403ffda",1,true ,2,1,0,0, false, 22}, // title=Barnyard Blaster
|
||||
{"babe2bc2976688bafb8b23c192658126",1,true, 2,1,1,0, false, 22}, // title=Barnyard Blaster
|
||||
{"f5f6b69c5eb4b55fc163158d1a6b423e",4,false,1,1,0,0, false, 22}, // title=Basketbrawl
|
||||
{"fba002089fcfa176454ab507e0eb76cb",4,false,1,1,1,0, false, 22}, // title=Basketbrawl
|
||||
{"78b1061d651ef806becac1dd3fda29a0",0,true ,1,1,0,0, true, 16}, // title=Beef Drop (Final Atariage)
|
||||
{"4e325918a8b3bbcf2f9405040abcfc6d",0,false,1,1,0,0, true, 26}, // title=BonQ (found on Atairage Age site ... no graphical glitches)
|
||||
{"9fa7743a016c9b7015ee1d386326f88e",0,false,1,1,0,0, true, 26}, // title=BonQ (final Atariage ... some graphical glitches)
|
||||
{"5a09946e57dbe30408a8f253a28d07db",0,false,1,1,0,0, true, 22}, // title=Centipede
|
||||
{"38c056a48472d9a9e16ebda5ed91dae7",0,false,1,1,1,0, false, 22}, // title=Centipede
|
||||
{"93e4387864b014c155d7c17877990d1e",0,false,1,1,0,0, false, 22}, // title=Choplifter
|
||||
{"59d4edb0230b5acc918b94f6bc94779f",0,false,1,1,1,0, false, 22}, // title=Choplifter
|
||||
{"2e8e28f6ad8b9b9267d518d880c73ebb",1,true ,1,1,0,0, false, 22}, // title=Commando
|
||||
{"55da6c6c3974d013f517e725aa60f48e",1,true ,1,1,1,0, false, 22}, // title=Commando
|
||||
{"db691469128d9a4217ec7e315930b646",1,false,1,1,0,0, false, 22}, // title=Crack'ed
|
||||
{"7cbe78fa06f47ba6516a67a4b003c9ee",1,false,1,1,1,0, false, 22}, // title=Crack'ed
|
||||
{"a94e4560b6ad053a1c24e096f1262ebf",2,false,3,3,0,0, false, 22}, // title=Crossbow
|
||||
{"63db371d67a98daec547b2abd5e7aa95",2,false,3,3,1,0, false, 22}, // title=Crossbow
|
||||
{"179b76ff729d4849b8f66a502398acae",1,false,1,1,0,0, false, 21}, // title=Dark Chambers
|
||||
{"a2b8e2f159642c4b91de82e9a2928494",1,false,1,1,1,0, false, 21}, // title=Dark Chambers
|
||||
{"77f4eea33705389a38c846081c7355fc",3,false,1,1,1,0, false, 22}, // title=Defender
|
||||
{"95ac811c7d27af0032ba090f28c107bd",0,false,1,1,0,0, false, 22}, // title=Desert Falcon
|
||||
{"2d5d99b993a885b063f9f22ce5e6523d",0,false,1,1,1,0, false, 22}, // title=Desert Falcon
|
||||
{"731879ea82fc0ca245e39e036fe293e6",0,false,1,1,0,0, true, 22}, // title=Dig Dug
|
||||
{"408dca9fc40e2b5d805f403fa0509436",0,false,1,1,1,0, false, 22}, // title=Dig Dug
|
||||
{"5e332fbfc1e0fc74223d2e73271ce650",0,false,1,1,0,0, false, 22}, // title=Donkey Kong Jr
|
||||
{"4dc5f88243250461bd61053b13777060",0,false,1,1,1,0, false, 22}, // title=Donkey Kong Jr
|
||||
{"19f1ee292a23636bd57d408b62de79c7",0,false,1,1,0,0, false, 22}, // title=Donkey Kong
|
||||
{"8e96ef14ce9b5d84bcbc996b66d6d4c7",0,false,1,1,1,0, false, 22}, // title=Donkey Kong
|
||||
{"543484c00ba233736bcaba2da20eeea9",6,false,1,1,0,3, false, 22}, // title=Double Dragon
|
||||
{"de2ebafcf0e37aaa9d0e9525a7f4dd62",6,false,1,1,1,3, false, 22}, // title=Double Dragon
|
||||
{"b3143adbbb7d7d189e918e5b29d55a72",0,true ,1,1,0,0, true, 22}, // title=Dungeon Stalker (homebrew)
|
||||
{"2251a6a0f3aec84cc0aff66fc9fa91e8",5,false,1,1,0,0, false, 22}, // title=F-18 Hornet
|
||||
{"e7709da8e49d3767301947a0a0b9d2e6",5,false,1,1,1,0, false, 22}, // title=F-18 Hornet
|
||||
{"6287727ab36391a62f728bbdee88675c",0,false,1,1,0,0, true, 22}, // title=Failsafe (homebrew)
|
||||
{"d25d5d19188e9f149977c49eb0367cd1",4,false,1,1,0,0, false, 22}, // title=Fatal Run
|
||||
{"23505651ac2e47f3637152066c3aa62f",4,false,1,1,1,0, false, 22}, // title=Fatal Run
|
||||
{"07dbbfe612a0a28e283c01545e59f25e",4,false,1,1,0,0, false, 22}, // title=Fight Night
|
||||
{"e80f24e953563e6b61556737d67d3836",4,false,1,1,1,0, false, 22}, // title=Fight Night
|
||||
{"cf76b00244105b8e03cdc37677ec1073",0,false,1,1,0,0, true, 22}, // title=Food Fight
|
||||
{"de0d4f5a9bf1c1bddee3ed2f7ec51209",0,false,1,1,1,0, false, 22}, // title=Food Fight
|
||||
{"e7d89669a7f92ec2cc99d9663a28671c",0,false,1,1,0,0, true, 18}, // title=Frenzy (with Berzerk) (homebrew)
|
||||
{"6053233cb59c0b4ca633623fd76c4576",0,true, 1,1,0,0, true, 13}, // title=Froggie (homebrew)
|
||||
{"fb8d803b328b2e442548f7799cfa9a4a",0,false,1,1,0,0, true, 22}, // title=Galaga
|
||||
{"f5dc7dc8e38072d3d65bd90a660148ce",0,false,1,1,1,0, false, 22}, // title=Galaga
|
||||
{"06204dadc975be5e5e37e7cc66f984cf",0,false,1,1,0,0, false, 22}, // title=Gato
|
||||
{"fd9e78e201b6baafddfd3e1fbfe6ba31",0,false,1,1,0,0, false, 22}, // title=Hat Trick
|
||||
{"0baec96787ce17f390e204de1a136e59",0,false,1,1,1,0, false, 22}, // title=Hat Trick
|
||||
{"c3672482ca93f70eafd9134b936c3feb",4,false,1,1,0,0, false, 22}, // title=Ikari Warriors
|
||||
{"8c2c2a1ea6e9a928a44c3151ba5c1ce3",4,false,1,1,1,0, false, 22}, // title=Ikari Warriors
|
||||
{"baebc9246c087e893dfa489632157180",3,false,1,1,0,0, false, 22}, // title=Impossible Mission
|
||||
{"1745feadabb24e7cefc375904c73fa4c",3,false,1,1,0,0, false, 22}, // title=Impossible Mission
|
||||
{"80dead01ea2db5045f6f4443faa6fce8",3,false,1,1,1,0, false, 22}, // title=Impossible Mission
|
||||
{"045fd12050b7f2b842d5970f2414e912",3,false,1,1,0,0, false, 22}, // title=Jinks
|
||||
{"dfb86f4d06f05ad00cf418f0a59a24f7",3,false,1,1,1,0, false, 22}, // title=Jinks
|
||||
{"f18b3b897a25ab3885b43b4bd141b396",0,false,1,1,0,0, true, 22}, // title=Joust
|
||||
{"f2dae0264a4b4a73762b9d7177e989f6",0,false,1,1,1,0, false, 22}, // title=Joust
|
||||
{"c3a5a8692a423d43d9d28dd5b7d109d9",0,false,1,1,0,0, false, 22}, // title=Karateka
|
||||
{"5e0a1e832bbcea6facb832fde23a440a",1,false,1,1,1,0, false, 22}, // title=Karateka
|
||||
{"17b3b764d33eae9b5260f01df7bb9d2f",4,false,1,1,0,0, false, 22}, // title=Klax
|
||||
{"f57d0af323d4e173fb49ed447f0563d7",0,false,1,1,0,3, false, 22}, // title=Kung Fu Master
|
||||
{"2931b75811ad03f3ac9330838f3d231b",0,false,1,1,1,3, false, 22}, // title=Kung Fu Master
|
||||
{"431ca060201ee1f9eb49d44962874049",0,false,1,1,0,0, false, 22}, // title=Mario Bros.
|
||||
{"d2e861306be78e44248bb71d7475d8a3",0,false,1,1,1,0, false, 22}, // title=Mario Bros.
|
||||
{"37b5692e33a98115e574185fa8398c22",4,false,1,1,0,0, false, 22}, // title=Mat Mania Challenge
|
||||
{"6819c37b96063b024898a19dbae2df54",4,false,1,1,1,0, false, 22}, // title=Mat Mania Challenge
|
||||
{"f2f5e5841e4dda89a2faf8933dc33ea6",4,false,1,1,0,0, false, 22}, // title=Mean 18 Ultimate Golf
|
||||
{"2e9dbad6c0fa381a6cd1bb9abf98a104",4,false,1,1,1,0, false, 22}, // title=Mean 18 Ultimate Golf
|
||||
{"bedc30ec43587e0c98fc38c39c1ef9d0",4,false,2,2,0,0, false, 22}, // title=Meltdown
|
||||
{"c80155d7eec9e3dcb79aa6b83c9ccd1e",4,false,2,2,1,0, false, 22}, // title=Meltdown
|
||||
{"c3f6201d6a9388e860328c963a3301cc",0,false,1,1,0,0, true, 21}, // title=Meteor Shower
|
||||
{"bc1e905db1008493a9632aa83ab4682b",4,false,1,1,0,0, false, 22}, // title=Midnight Mutants
|
||||
{"6794ea31570eba0b88a0bf1ead3f3f1b",4,false,1,1,1,0, false, 22}, // title=Midnight Mutants
|
||||
{"017066f522908081ec3ee624f5e4a8aa",2,false,1,1,0,3, false, 22}, // title=Missing in Action
|
||||
{"3bc8f554cf86f8132a623cc2201a564b",4,false,1,1,0,0, false, 22}, // title=Motor Psycho
|
||||
{"5330bfe428a6b601b7e76c2cfc4cd049",4,false,1,1,1,0, false, 22}, // title=Motor Psycho
|
||||
{"fc0ea52a9fac557251b65ee680d951e5",0,false,1,1,0,0, true, 22}, // title=Ms. Pac-Man
|
||||
{"56469e8c5ff8983c6cb8dadc64eb0363",0,false,1,1,1,0, false, 22}, // title=Ms. Pac-Man
|
||||
{"220121f771fc4b98cef97dc040e8d378",4,false,1,1,0,0, false, 22}, // title=Ninja Golf
|
||||
{"ea0c859aa54fe5eaf4c1f327fab06221",4,false,1,1,1,0, false, 22}, // title=Ninja Golf
|
||||
{"74569571a208f8b0b1ccfb22d7c914e1",0,false,1,1,0,0, false, 12}, // title=One On One
|
||||
{"8dba0425f0262e5704581d8757a1a6e3",0,false,1,1,1,0, false, 12}, // title=One On One
|
||||
{"5013b69cb05b21a1194ce48517df7bfc",0,true, 1,1,0,0, true, 19}, // title=Pac-Man Collection (homebrew)
|
||||
{"044657294450c869c45e7ef61f4870de",1,true, 1,1,0,0, true, 27}, // title=Pac-Man Collection 40th Anniversary Edition (homebrew)
|
||||
{"1a5207870dec6fae9111cb747e20d8e3",0,false,1,1,0,0, false, 22}, // title=Pete Rose Baseball
|
||||
{"386bded4a944bae455fedf56206dd1dd",0,false,1,1,1,0, false, 22}, // title=Pete Rose Baseball
|
||||
{"ec206c8db4316eb1ebce9fc960da7d8f",4,false,1,1,0,0, false, 22}, // title=Pit Fighter
|
||||
{"33aea1e2b6634a1dec8c7006d9afda22",4,false,1,1,0,0, false, 18}, // title=Planet Smashers
|
||||
{"2837a8fd49b7fc7ccd70fd45b69c5099",4,false,1,1,1,0, false, 18}, // title=Planet Smashers
|
||||
{"584582bb09ee8122e7fc09dc7d1ed813",0,false,1,1,0,0, false, 22}, // title=Pole Position II
|
||||
{"865457e0e0f48253b08f77b9e18f93b2",0,false,1,1,1,0, false, 22}, // title=Pole Position II
|
||||
{"1745feadabb24e7cefc375904c73fa4c",3,false,1,1,0,0, false, 22}, // title=Possible Mission
|
||||
{"ac03806cef2558fc795a7d5d8dba7bc0",6,false,1,1,0,0, false, 22}, // title=Rampage
|
||||
{"bfad016d6e77eaccec74c0340aded8b9",1,false,1,1,0,0, false, 22}, // title=Realsports Baseball
|
||||
{"8f7eb10ad0bd75474abf0c6c36c08486",0,false,1,1,0,0, false, 22}, // title=Rescue On Fractalus
|
||||
{"66ecaafe1b82ae68ffc96267aaf7a4d7",0,false,1,1,0,0, true, 22}, // title=Robotron
|
||||
{"a3a85e507d6f718972b1464ce1aaf8a4",0,false,1,1,0,0, true, 13}, // title=Scramble (homebrew)
|
||||
{"980c35ae9625773a450aa7ef51751c04",4,false,1,1,0,0, false, 22}, // title=Scrapyard Dog
|
||||
{"53db322c201323fe2ca8f074c0a2bf86",4,false,1,1,1,0, false, 22}, // title=Scrapyard Dog
|
||||
{"b697d9c2d1b9f6cb21041286d1bbfa7f",4,true ,2,2,0,0, false, 22}, // title=Sentinel
|
||||
{"5469b4de0608f23a5c4f98f331c9e75f",4,true ,2,2,1,0, false, 22}, // title=Sentinel
|
||||
{"771cb4609347657f63e6f0eb26036e35",0,false,1,1,0,0, true, 22}, // title=Space Duel (homebrew)
|
||||
{"6adf79558a3d7f5beca1bb8d34337417",0,false,1,1,0,0, true, 99}, // title=Space Invaders (Homebrew) Special 99=340 pixel mode...
|
||||
{"cbb0746192540a13b4c7775c7ce2021f",3,false,1,1,0,0, false, 22}, // title=Summer Games
|
||||
{"81cee326b99d6831de10a566e338bd25",0,true, 1,1,0,0, true, 21}, // title=Super Circus Atariage (Pokey 4000)
|
||||
{"cc18e3b37a507c4217eb6cb1de8c8538",0,false,1,1,0,0, false, 22}, // title=Super Huey UH-IX
|
||||
{"162f9c953f0657689cc74ab20b40280f",0,false,1,1,1,0, false, 22}, // title=Super Huey UH-IX
|
||||
{"59b5793bece1c80f77b55d60fb39cb94",0,false,1,1,0,0, false, 22}, // title=Super Skatebordin'
|
||||
{"95d7c321dce8f57623a9c5b4947bb375",0,false,1,1,1,0, false, 22}, // title=Super Skatebordin'
|
||||
{"44f862bca77d68b56b32534eda5c198d",1,false,1,1,0,0, false, 22}, // title=Tank Command
|
||||
{"1af475ff6429a160752b592f0f92b287",0,false,1,1,0,0, false, 22}, // title=Title Match Pro Wrestling
|
||||
{"3bb9c8d9adc912dd7f8471c97445cd8d",0,false,1,1,1,0, false, 22}, // title=Title Match Pro Wrestling
|
||||
{"c3903ab01a51222a52197dbfe6538ecf",0,false,1,1,0,0, false, 22}, // title=Tomcat F-14 Simulator
|
||||
{"682338364243b023ecc9d24f0abfc9a7",0,false,1,1,1,0, false, 22}, // title=Tomcat F-14 Simulator
|
||||
{"208ef955fa90a29815eb097bce89bace",4,false,1,1,0,0, false, 22}, // title=Touchdown Football
|
||||
{"d12e665347f354048b9d13092f7868c9",3,false,1,1,0,0, false, 22}, // title=Tower Toppler
|
||||
{"32a37244a9c6cc928dcdf02b45365aa8",3,false,1,1,1,0, false, 22}, // title=Tower Toppler
|
||||
{"acf63758ecf3f3dd03e9d654ae6b69b7",1,false,1,1,0,0, false, 22}, // title=Water Ski
|
||||
{"3799d72f78dda2ee87b0ef8bf7b91186",3,false,1,1,0,0, false, 22}, // title=Winter Games
|
||||
{"05fb699db9eef564e2fe45c568746dbc",4,false,1,1,0,0, false, 22}, // title=Xenophobe
|
||||
{"70937c3184f0be33d06f7f4382ca54de",4,false,1,1,1,0, false, 22}, // title=Xenophobe
|
||||
{"d7dc17379aa25e5ae3c14b9e780c6f6d",0,false,1,1,0,0, true, 22}, // title=Xevious
|
||||
{"b1a9f196ce5f47ca8caf8fa7bc4ca46c",0,false,1,1,1,0, false, 22}, // 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},
|
||||
{"",0,false,0,0,0,0},
|
||||
};
|
||||
|
||||
|
||||
|
||||
NameMap_t NameMap[] =
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool database_Load(byte *digest)
|
||||
{
|
||||
{"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"},
|
||||
|
||||
{"","",""}
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 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)
|
||||
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 */
|
||||
for(i = 0; strlen(game_list[i].digest); i++)
|
||||
{
|
||||
// --------------------------------------------------------------------------------------
|
||||
// First see if we've got a match in our external A7800DS.DAT configuration database...
|
||||
// --------------------------------------------------------------------------------------
|
||||
for(i = 0; i < MAX_CONFIGS; i++)
|
||||
{
|
||||
if(!strncmp(allConfigs.cart[i].half_digest, (char *) digest, 16))
|
||||
{
|
||||
memcpy( & myCartInfo, & allConfigs.cart[i], sizeof(myCartInfo));
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!strcmp(game_list[i].digest,(char *) digest))
|
||||
{
|
||||
cartridge_type = game_list[i].cardtype;
|
||||
cartridge_pokey = game_list[i].pokey;
|
||||
cartridge_controller[0] = game_list[i].cardctrl1;
|
||||
cartridge_controller[1] = game_list[i].cardctrl2;
|
||||
cartridge_region = game_list[i].cardregion;
|
||||
cartridge_flags = game_list[i].cardflags;
|
||||
cartridge_hsc_enabled = game_list[i].hsc;
|
||||
cartridge_yOffset = game_list[i].yOffset;
|
||||
cartridge_wsync = !( cartridge_flags & CARTRIDGE_WSYNC_MASK );
|
||||
cartridge_cycle_stealing = !( cartridge_flags & CARTRIDGE_CYCLE_STEALING_MASK );
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
cartridge_yOffset = 22;
|
||||
}
|
||||
cartridge_xOffset = 0;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
return true;
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
||||
|
|
|
@ -27,61 +27,9 @@
|
|||
|
||||
#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,7 +25,6 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "Hash.h"
|
||||
#include "../printf.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Step1
|
||||
|
@ -232,7 +231,9 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,316 +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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// 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"
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Saves the high score cartridge SRAM
|
||||
*
|
||||
* return Whether the save was successful (false if game is not supporting HSC)
|
||||
*/
|
||||
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)
|
||||
{
|
||||
return false; // If we didn't load the high score cartridge, or don't have an HSC enabled cart: don't save.
|
||||
}
|
||||
|
||||
// Make sure something actually changed before writing...
|
||||
if (memcmp(high_score_sram, memory_ram+HS_SRAM_START, HS_SRAM_SIZE) != 0)
|
||||
{
|
||||
memcpy(high_score_sram, memory_ram+HS_SRAM_START, HS_SRAM_SIZE); // Copy from main memory to SRAM buffer
|
||||
|
||||
make_hsc_name(); // HSC filename is same as base filename with .hsc extension
|
||||
|
||||
// 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 true; // We at least made the attempt to write out the .hsc save file
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the high score cartridge SRAM
|
||||
*
|
||||
* return Whether the load was successful
|
||||
*/
|
||||
static bool cartridge_LoadHighScoreSram(void)
|
||||
{
|
||||
if(!high_score_cart_loaded || !myCartInfo.hsc)
|
||||
{
|
||||
return false; // If we didn't load the high score cartridge, or don't have an HSC enabled cart: don't save.
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
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!
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the high score cartridge
|
||||
*
|
||||
* return Whether the load was successful
|
||||
*/
|
||||
bool cartridge_LoadHighScoreCart(void)
|
||||
{
|
||||
if( !myCartInfo.hsc || myCartInfo.region != 0 )
|
||||
{
|
||||
return false; // Only load the cart if it is enabled and the region is NTSC
|
||||
}
|
||||
|
||||
FILE* file = fopen("highscore.rom", "rb" );
|
||||
|
||||
// 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_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
|
||||
{
|
||||
high_score_cart_loaded = false;
|
||||
}
|
||||
|
||||
return high_score_cart_loaded;
|
||||
}
|
||||
|
||||
// End of file
|
154
arm9/source/emu/Logger.c
Normal file
|
@ -0,0 +1,154 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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
|
65
arm9/source/emu/Logger.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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
|
|
@ -24,21 +24,30 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#ifndef MARIA_H
|
||||
#define MARIA_H
|
||||
# if 0 //LUDO:
|
||||
#define MARIA_SURFACE_SIZE 93440
|
||||
# else
|
||||
#define MARIA_SURFACE_SIZE 77440
|
||||
# endif
|
||||
|
||||
#define MARIA_SURFACE_SIZE (128*1024) // DS screen buffer size
|
||||
// 93440 = 320 x 292
|
||||
// 77440 = 320 x 242
|
||||
|
||||
#include "Equates.h"
|
||||
#include "Pair.h"
|
||||
#include "Memory.h"
|
||||
#include "Rect.h"
|
||||
#include "Sally.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
|
||||
extern void maria_Reset( );
|
||||
extern void maria_RenderScanline(void);
|
||||
extern void maria_RenderScanlineTOP(void);
|
||||
extern ITCM_CODE uint maria_RenderScanline( );
|
||||
extern void maria_Clear( );
|
||||
extern rect maria_displayArea;
|
||||
extern rect maria_visibleArea;
|
||||
extern word* maria_surface;
|
||||
extern uint maria_scanline;
|
||||
extern word maria_scanline;
|
||||
|
||||
#endif
|
||||
|
|
530
arm9/source/emu/Maria.itcm.c
Normal file
|
@ -0,0 +1,530 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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;
|
||||
|
||||
#define MARIA_LINERAM_SIZE 160
|
||||
|
||||
rect maria_displayArea = {0, 16, 319, 258};
|
||||
rect maria_visibleArea = {0, 26, 319, 248};
|
||||
|
||||
word* maria_surface = 0;
|
||||
word maria_scanline = 1;
|
||||
|
||||
static byte maria_lineRAM[MARIA_LINERAM_SIZE+4];
|
||||
static uint maria_cycles;
|
||||
static pair maria_dpp;
|
||||
static pair maria_dp;
|
||||
static pair maria_pp;
|
||||
static byte maria_horizontal;
|
||||
static byte maria_palette;
|
||||
static char maria_offset;
|
||||
static byte maria_h08;
|
||||
static byte maria_h16;
|
||||
static byte maria_wmode;
|
||||
|
||||
static inline void _maria_ClearCells(void)
|
||||
{
|
||||
if(maria_horizontal < MARIA_LINERAM_SIZE)
|
||||
{
|
||||
if (memory_ram[CTRL] & 4)
|
||||
{
|
||||
*((u16 *)&maria_lineRAM[maria_horizontal]) = 0;
|
||||
}
|
||||
}
|
||||
maria_horizontal += 2;
|
||||
}
|
||||
|
||||
static inline void _maria_ClearCells4(void)
|
||||
{
|
||||
if(maria_horizontal < MARIA_LINERAM_SIZE)
|
||||
{
|
||||
if (memory_ram[CTRL] & 4)
|
||||
{
|
||||
*((u32 *)&maria_lineRAM[maria_horizontal]) = 0;
|
||||
}
|
||||
}
|
||||
maria_horizontal += 4;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreCell
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void _maria_StoreCells4(byte data)
|
||||
{
|
||||
if((maria_horizontal+3) < MARIA_LINERAM_SIZE)
|
||||
{
|
||||
byte *ptr = &(maria_lineRAM[maria_horizontal+3]);
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static inline void maria_StoreCellWide(byte data)
|
||||
{
|
||||
if((maria_horizontal+1) < MARIA_LINERAM_SIZE)
|
||||
{
|
||||
byte mp = (maria_palette & 16);
|
||||
maria_lineRAM[maria_horizontal++] = mp | (data >> 4);
|
||||
maria_lineRAM[maria_horizontal++] = mp | (data & 0x0F);
|
||||
} else maria_horizontal += 2;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreCell
|
||||
// ----------------------------------------------------------------------------
|
||||
static inline void maria_ClearCellWide(void)
|
||||
{
|
||||
if(memory_ram[CTRL] & 4)
|
||||
{
|
||||
byte *ptr = (byte *)&maria_lineRAM[maria_horizontal];
|
||||
if(maria_horizontal < MARIA_LINERAM_SIZE) *ptr++ = 0;
|
||||
maria_horizontal++;
|
||||
if(maria_horizontal < MARIA_LINERAM_SIZE) *ptr = 0;
|
||||
maria_horizontal++;
|
||||
}
|
||||
else 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] =
|
||||
{
|
||||
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() || !data)
|
||||
{
|
||||
maria_ClearCellWide();
|
||||
}
|
||||
else
|
||||
{
|
||||
maria_StoreCellWide(wide_lookup[data]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(maria_IsHolyDMA() || !data)
|
||||
{
|
||||
_maria_ClearCells4();
|
||||
}
|
||||
else
|
||||
{
|
||||
_maria_StoreCells4(data);
|
||||
}
|
||||
}
|
||||
maria_pp.w++;
|
||||
}
|
||||
|
||||
static u8 wide_lookup_mode2A[] =
|
||||
{
|
||||
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[] =
|
||||
{
|
||||
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;
|
||||
//memset(maria_lineRAM, 0, MARIA_LINERAM_SIZE);
|
||||
*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
|
||||
// ----------------------------------------------------------------------------
|
||||
word *framePtr = (word *)0;
|
||||
ITCM_CODE uint maria_RenderScanline( )
|
||||
{
|
||||
extern int gTotalAtariFrames;
|
||||
maria_cycles = 0;
|
||||
|
||||
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,348 +22,187 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Memory.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "ProSystem.h"
|
||||
#include "Memory.h"
|
||||
#include "Maria.h"
|
||||
#include "Database.h"
|
||||
|
||||
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;
|
||||
byte memory_ram[MEMORY_SIZE] = {0};
|
||||
byte memory_rom[MEMORY_SIZE] = {0};
|
||||
//ALEK byte *memory_rom = memory_ram;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_Reset()
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// AM_RANGE(0x0020, 0x003f) AM_MIRROR(0x300) AM_READWRITE(a7800_MARIA_r, a7800_MARIA_w)
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE byte memory_Read_Slower(word address)
|
||||
{
|
||||
extern u8 write_only_pokey_at_4000;
|
||||
ITCM_CODE byte memory_Read(word address) {
|
||||
byte tmp_byte;
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
switch ( address ) {
|
||||
case INTIM:
|
||||
case INTIM | 0x2:
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return memory_ram[INTIM];
|
||||
break;
|
||||
case INTFLG:
|
||||
case INTFLG | 0x2:
|
||||
tmp_byte = memory_ram[INTFLG];
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return tmp_byte;
|
||||
break;
|
||||
default:
|
||||
return memory_ram[address];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Write
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void memory_Write(word address, byte data)
|
||||
{
|
||||
extern u32 bg32, maria_charbase;
|
||||
extern u8 bg8;
|
||||
ITCM_CODE void memory_Write(word address, byte data) {
|
||||
//ALEK void memory_Write(byte data,word address) {
|
||||
|
||||
if(unlikely(myCartInfo.pokeyType))
|
||||
{
|
||||
if(myCartInfo.pokeyType == POKEY_AT_4000)
|
||||
{
|
||||
if((address & 0xFFF0) == 0x4000)
|
||||
{
|
||||
pokey_SetRegister(address, data);
|
||||
return;
|
||||
}
|
||||
if(!memory_rom[address]) {
|
||||
switch(address) {
|
||||
case INPTCTRL:
|
||||
if(data == 22 && cartridge_IsLoaded( )) {
|
||||
cartridge_Store( );
|
||||
}
|
||||
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 & 0x0F), data);
|
||||
return;
|
||||
}
|
||||
if((address & 0xFFF0) == 0x800) // Pokey @800
|
||||
{
|
||||
pokey_SetRegister(0x4000 | (address & 0x0F), data);
|
||||
return;
|
||||
}
|
||||
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;
|
||||
//#define WSYNC 36 -> 0x24
|
||||
case WSYNC:
|
||||
if(!(cartridge_flags & 128)) {
|
||||
memory_ram[WSYNC] = true;
|
||||
}
|
||||
break;
|
||||
// #define SWCHB 642 -> 0x282
|
||||
//#define CTLSWB 643
|
||||
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);
|
||||
// case CTLSWB:
|
||||
break;
|
||||
// #define TIM1T 660
|
||||
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;
|
||||
// 0x2040 -> 0x20ff (0x2000)
|
||||
if(address >= 8256 && address <= 8447) {
|
||||
memory_ram[address - 8192] = data;
|
||||
}
|
||||
// 0x2140 -> 0x21fe (0x2000)
|
||||
else if(address >= 8512 && address <= 8702) {
|
||||
memory_ram[address - 8192] = data;
|
||||
}
|
||||
// 0x40 -> 0xff (0x2000)
|
||||
else if(address >= 64 && address <= 255) {
|
||||
memory_ram[address + 8192] = data;
|
||||
}
|
||||
// 0x140 -> 0x1ff (0x2000)
|
||||
else if(address >= 320 && address <= 511) {
|
||||
memory_ram[address + 8192] = data;
|
||||
}
|
||||
cartridge_Write(address, data);
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
else {
|
||||
cartridge_Write(address, data);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WriteROM
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void memory_WriteROM(word address, u32 size, const byte * data)
|
||||
{
|
||||
memcpy( & memory_ram[address], data, size);
|
||||
memset( & is_memory_writable[address >> 8], 0x00, size >> 8);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// 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, u32 size, const u32 * data)
|
||||
{
|
||||
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++;
|
||||
void memory_WriteROM(word address, word size, const byte* data) {
|
||||
uint index;
|
||||
if((address + size) <= MEMORY_SIZE && data != NULL) {
|
||||
for(index = 0; index < size; index++) {
|
||||
memory_ram[address + index] = data[index];
|
||||
memory_rom[address + index] = 1;
|
||||
}
|
||||
while(--size2);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ClearROM
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_ClearROM(word address, word size)
|
||||
{
|
||||
memset( & memory_ram[address], 0x00, size);
|
||||
memset( & is_memory_writable[address >> 8], 0xFF, size >> 8);
|
||||
void memory_ClearROM(word address, word size) {
|
||||
uint index;
|
||||
if((address + size) <= MEMORY_SIZE) {
|
||||
for(index = 0; index < size; index++) {
|
||||
memory_ram[address + index] = 0;
|
||||
memory_rom[address + index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,31 +27,23 @@
|
|||
#define MEMORY_SIZE 65536
|
||||
|
||||
#include "Equates.h"
|
||||
#include "Bios.h"
|
||||
#include "Cartridge.h"
|
||||
#include "Tia.h"
|
||||
#include "Riot.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
extern u8 bHSC_dirty;
|
||||
|
||||
extern byte memory_ram[MEMORY_SIZE];
|
||||
extern void memory_Reset( );
|
||||
extern ITCM_CODE byte memory_Read(word address);
|
||||
extern ITCM_CODE void memory_Write(word address, byte data);
|
||||
//ALEK extern void memory_Write(byte data,word address);
|
||||
|
||||
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_WriteROM(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 byte* get_memory_ram();
|
||||
|
||||
|
|
|
@ -37,17 +37,4 @@ 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;
|
||||
|
||||
// Taken from Wii Port 0.5
|
||||
bool palette_default = true;
|
||||
// 1.3
|
||||
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,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,
|
||||
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,0x8B,0x00,
|
||||
0x00,0xA9,0x00,0x00,0xBB,0x05,0x00,0xBD,0x00,0x02,0xD0,0x05,
|
||||
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,
|
||||
|
@ -94,21 +94,115 @@ 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) {
|
||||
u16 index;
|
||||
uint 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,11 +27,15 @@
|
|||
#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
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#include <stdlib.h>
|
||||
#include "Pokey.h"
|
||||
#include "ProSystem.h"
|
||||
|
||||
#define POKEY_NOTPOLY5 0x80
|
||||
#define POKEY_POLY4 0x40
|
||||
#define POKEY_PURE 0x20
|
||||
|
@ -67,68 +65,35 @@
|
|||
#define POKEY_CHANNEL4 3
|
||||
#define POKEY_SAMPLE 4
|
||||
|
||||
#define SK_RESET 0x03
|
||||
|
||||
extern byte TIA_POLY4[];
|
||||
extern byte TIA_POLY5[];
|
||||
|
||||
u32 pokeyBufIdx __attribute__((section(".dtcm"))) = 0;
|
||||
byte pokey_buffer[POKEY_BUFFER_SIZE] = {0};
|
||||
uint pokey_size = 524;
|
||||
|
||||
static uint pokey_frequency = 1787520;
|
||||
static uint pokey_sampleRate = (31440/2);
|
||||
static uint pokey_audf[4];
|
||||
static uint pokey_audc[4];
|
||||
static uint pokey_audctl __attribute__((section(".dtcm")));
|
||||
static uint pokey_sampleRate = 31440;
|
||||
static uint pokey_soundCntr = 0;
|
||||
static byte pokey_audf[4];
|
||||
static byte pokey_audc[4];
|
||||
static byte pokey_audctl;
|
||||
static byte pokey_output[4];
|
||||
static byte pokey_outVol[4];
|
||||
#define pokey_poly04 TIA_POLY4
|
||||
#define pokey_poly05 TIA_POLY5
|
||||
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};
|
||||
static byte pokey_poly17[POKEY_POLY17_SIZE];
|
||||
static uint pokey_poly17Size;
|
||||
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_polyAdjust;
|
||||
static uint pokey_poly04Cntr;
|
||||
static uint pokey_poly05Cntr;
|
||||
static uint pokey_poly17Cntr;
|
||||
static uint pokey_divideMax[4];
|
||||
static uint pokey_divideCount[4];
|
||||
static uint pokey_sampleMax __attribute__((section(".dtcm")));
|
||||
static uint pokey_sampleMax;
|
||||
static uint pokey_sampleCount[2];
|
||||
static uint pokey_baseMultiplier;
|
||||
|
||||
static byte rand9[0x1ff];
|
||||
static byte rand17[0x1ffff];
|
||||
static uint r9;
|
||||
static uint r17;
|
||||
static byte SKCTL;
|
||||
|
||||
byte POT_input[8] = {228, 228, 228, 228, 228, 228, 228, 228};
|
||||
static int pot_scanline;
|
||||
|
||||
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)
|
||||
{
|
||||
int mask = (1 << size) - 1;
|
||||
int i, x = 0;
|
||||
|
||||
for( i = 0; i < mask; i++ )
|
||||
{
|
||||
if (size == 17)
|
||||
*rng = x >> 6; /* use bits 6..13 */
|
||||
else
|
||||
*rng = x; /* use bits 0..7 */
|
||||
rng++;
|
||||
/* calculate next bit */
|
||||
x = ((x << left) + (x >> right) + add) & mask;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void pokey_Reset( )
|
||||
{
|
||||
void pokey_Reset( ) {
|
||||
uint index, channel;
|
||||
for(index = 0; index < POKEY_POLY17_SIZE; index++) {
|
||||
pokey_poly17[index] = rand( ) & 1;
|
||||
|
@ -154,87 +119,18 @@ void pokey_Reset( )
|
|||
pokey_audf[channel] = 0;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
POT_input[i] = 228;
|
||||
}
|
||||
|
||||
pokey_audctl = 0;
|
||||
pokey_baseMultiplier = POKEY_DIV_64;
|
||||
|
||||
/* initialize the random arrays */
|
||||
rand_init(rand9, 9, 8, 1, 0x00180);
|
||||
rand_init(rand17, 17,16, 1, 0x1c000);
|
||||
|
||||
SKCTL = SK_RESET;
|
||||
|
||||
r9 = 0;
|
||||
r17 = 0;
|
||||
random_scanline_counter = 0;
|
||||
prev_random_scanline_counter = 0;
|
||||
|
||||
pokeyBufIdx=0;
|
||||
}
|
||||
|
||||
|
||||
byte pokey_GetRegister(word address)
|
||||
{
|
||||
byte data = 0;
|
||||
|
||||
if (address == POKEY_RANDOM)
|
||||
{
|
||||
uint32 curr_scanline_counter = ( random_scanline_counter + prosystem_cycles );
|
||||
|
||||
if( SKCTL & SK_RESET )
|
||||
{
|
||||
uint32 adjust = ( ( curr_scanline_counter - prev_random_scanline_counter ) >> 2 );
|
||||
r9 = (uint)((adjust + r9) % 0x001ff);
|
||||
r17 = (uint)((adjust + r17) % 0x1ffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
r9 = 0;
|
||||
r17 = 0;
|
||||
}
|
||||
byte RANDOM;
|
||||
if( pokey_audctl & POKEY_POLY9 )
|
||||
{
|
||||
RANDOM = rand9[r9];
|
||||
}
|
||||
else
|
||||
{
|
||||
RANDOM = rand17[r17];
|
||||
}
|
||||
|
||||
prev_random_scanline_counter = curr_scanline_counter;
|
||||
|
||||
RANDOM = RANDOM ^ 0xff;
|
||||
data = RANDOM;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetRegister
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void pokey_SetRegister(word address, byte value) {
|
||||
uint channelMask;
|
||||
void pokey_SetRegister(word address, byte value) {
|
||||
byte channelMask;
|
||||
uint channel;
|
||||
|
||||
|
||||
switch(address) {
|
||||
case POKEY_POTGO:
|
||||
if (!(SKCTL & 4))
|
||||
pot_scanline = 0; /* slow pot mode */
|
||||
return;
|
||||
|
||||
case POKEY_SKCTLS:
|
||||
SKCTL = value;
|
||||
if (value & 4)
|
||||
pot_scanline = 228; /* fast pot mode - return results immediately */
|
||||
return;
|
||||
|
||||
case POKEY_AUDF1:
|
||||
pokey_audf[POKEY_CHANNEL1] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL1;
|
||||
|
@ -304,8 +200,6 @@ ITCM_CODE void pokey_SetRegister(word address, byte value) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!channelMask) return;
|
||||
|
||||
uint newValue = 0;
|
||||
|
||||
if(channelMask & (1 << POKEY_CHANNEL1)) {
|
||||
|
@ -397,174 +291,90 @@ static inline uint loc_get_int(byte *p)
|
|||
|
||||
static inline void loc_set_byte(byte *p, uint v)
|
||||
{
|
||||
*((u32 *)p) = v;
|
||||
u32 *zz = (u32 *)p;
|
||||
*zz = v;
|
||||
}
|
||||
|
||||
extern u32 tiaBufIdx;
|
||||
// ----------------------------------------------------------------------------
|
||||
// Process
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void pokey_Process(void)
|
||||
void pokey_Process(uint length)
|
||||
{
|
||||
if (tia_wait) return;
|
||||
byte* buffer = pokey_buffer + pokey_soundCntr;
|
||||
byte* sampleCntrPtrB = ((byte*)&pokey_sampleCount[0]) + 1;
|
||||
uint size = length;
|
||||
|
||||
byte* sampleCntrPtrB = ((byte*)&pokey_sampleCount[0]) + 1;
|
||||
while(length)
|
||||
{
|
||||
byte 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;
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
int currentValue;
|
||||
uint 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
||||
u16 pokey_ProcessNow(void)
|
||||
{
|
||||
byte* sampleCntrPtrB = ((byte*)&pokey_sampleCount[0]) + 1;
|
||||
pokey_polyAdjust += eventMin;
|
||||
|
||||
while (1)
|
||||
if(nextEvent != POKEY_SAMPLE)
|
||||
{
|
||||
int currentValue;
|
||||
uint nextEvent = POKEY_SAMPLE;
|
||||
uint eventMin = loc_get_int(sampleCntrPtrB);
|
||||
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];
|
||||
|
||||
byte channel;
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
if(pokey_divideCount[channel] <= eventMin) {
|
||||
eventMin = pokey_divideCount[channel];
|
||||
nextEvent = channel;
|
||||
}
|
||||
if((pokey_audc[nextEvent] & POKEY_NOTPOLY5) || pokey_poly05[pokey_poly05Cntr]) {
|
||||
if(pokey_audc[nextEvent] & POKEY_PURE) {
|
||||
pokey_output[nextEvent] = !pokey_output[nextEvent];
|
||||
}
|
||||
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
pokey_divideCount[channel] -= eventMin;
|
||||
else if (pokey_audc[nextEvent] & POKEY_POLY4) {
|
||||
pokey_output[nextEvent] = pokey_poly04[pokey_poly04Cntr];
|
||||
}
|
||||
|
||||
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_output[nextEvent] = pokey_poly17[pokey_poly17Cntr];
|
||||
}
|
||||
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);
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
||||
currentValue = (currentValue << 2) + 8;
|
||||
*buffer++ = currentValue;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
pokey_soundCntr += size;
|
||||
if(pokey_soundCntr >= pokey_size)
|
||||
{
|
||||
pokey_soundCntr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -572,9 +382,8 @@ u16 pokey_ProcessNow(void)
|
|||
// ----------------------------------------------------------------------------
|
||||
void pokey_Clear( ) {
|
||||
uint index;
|
||||
for(index = 0; index < SNDLENGTH; index++) {
|
||||
tia_buffer[index] = 0;
|
||||
pokeyBufIdx=0;
|
||||
for(index = 0; index < POKEY_BUFFER_SIZE; index++) {
|
||||
pokey_buffer[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#ifndef POKEY_H
|
||||
#define POKEY_H
|
||||
#define POKEY_BUFFER_SIZE 624
|
||||
#define POKEY_AUDF1 0x4000
|
||||
#define POKEY_AUDC1 0x4001
|
||||
#define POKEY_AUDF2 0x4002
|
||||
|
@ -49,44 +50,15 @@
|
|||
#define POKEY_AUDF4 0x4006
|
||||
#define POKEY_AUDC4 0x4007
|
||||
#define POKEY_AUDCTL 0x4008
|
||||
#define POKEY_STIMER 0x4009
|
||||
#define POKEY_SKRES 0x400a
|
||||
#define POKEY_POTGO 0x400b
|
||||
#define POKEY_SEROUT 0x400d
|
||||
#define POKEY_IRQEN 0x400e
|
||||
#define POKEY_SKCTLS 0x400f
|
||||
|
||||
#define POKEY_POT0 0x4000
|
||||
#define POKEY_POT1 0x4001
|
||||
#define POKEY_POT2 0x4002
|
||||
#define POKEY_POT3 0x4003
|
||||
#define POKEY_POT4 0x4004
|
||||
#define POKEY_POT5 0x4005
|
||||
#define POKEY_POT6 0x4006
|
||||
#define POKEY_POT7 0x4007
|
||||
#define POKEY_ALLPOT 0x4008
|
||||
#define POKEY_KBCODE 0x4009
|
||||
#define POKEY_RANDOM 0x400a
|
||||
#define POKEY_SERIN 0x400d
|
||||
#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(void);
|
||||
extern u16 pokey_ProcessNow(void);
|
||||
extern void pokey_Process(uint length);
|
||||
extern void pokey_Clear( );
|
||||
extern uint32 random_scanline_counter;
|
||||
|
||||
/* Called prior to each scanline */
|
||||
inline void pokey_Scanline()
|
||||
{
|
||||
random_scanline_counter += CYCLES_PER_SCANLINE;
|
||||
}
|
||||
|
||||
extern byte pokey_buffer[POKEY_BUFFER_SIZE];
|
||||
extern uint pokey_size;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,168 +23,357 @@
|
|||
// ProSystem.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <malloc.h>
|
||||
#include "ProSystem.h"
|
||||
#include "Database.h"
|
||||
#include "Sound.h"
|
||||
#define PRO_SYSTEM_SOURCE "ProSystem.cpp"
|
||||
#define PRO_SYSTEM_STATE_HEADER "PRO-SYSTEM STATE"
|
||||
|
||||
extern u8 isDS_LITE;
|
||||
extern u8 frameSkipMask;
|
||||
#define CYCLES_PER_SCANLINE 454
|
||||
|
||||
uint prosystem_cycles __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)
|
||||
bool prosystem_active = false;
|
||||
bool prosystem_paused = false;
|
||||
word prosystem_frequency = 60;
|
||||
word prosystem_scanlines = 262;
|
||||
uint prosystem_cycles = 0;
|
||||
|
||||
// Whether the last CPU operation resulted in a half cycle (need to take it
|
||||
// into consideration)
|
||||
extern bool half_cycle;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Reset()
|
||||
{
|
||||
if(cartridge_IsLoaded())
|
||||
{
|
||||
sally_Reset();
|
||||
region_Reset();
|
||||
tia_Clear();
|
||||
tia_Reset();
|
||||
pokey_Clear();
|
||||
pokey_Reset();
|
||||
memory_Reset();
|
||||
maria_Clear();
|
||||
maria_Reset();
|
||||
riot_Reset();
|
||||
cartridge_LoadHighScoreCart();
|
||||
void prosystem_Reset( ) {
|
||||
if(cartridge_IsLoaded( )) {
|
||||
prosystem_paused = false;
|
||||
|
||||
cartridge_Store(); // Always call this - it may setup some RAM or other stuff below the BIOS region...
|
||||
sally_Reset( ); // WII
|
||||
|
||||
// Load 7800 BIOS if available... otherwise direct load the CART
|
||||
if(bios_available && !bSkipBIOS)
|
||||
{
|
||||
bios_Store();
|
||||
bios_show_counter = myCartInfo.biosTimeout;
|
||||
}
|
||||
|
||||
prosystem_cycles = sally_ExecuteRES();
|
||||
region_Reset( );
|
||||
tia_Clear( );
|
||||
tia_Reset( );
|
||||
pokey_Clear( );
|
||||
pokey_Reset( );
|
||||
memory_Reset( );
|
||||
maria_Clear( );
|
||||
maria_Reset( );
|
||||
riot_Reset ( );
|
||||
if(bios_enabled) {
|
||||
bios_Store( );
|
||||
}
|
||||
else {
|
||||
cartridge_Store( );
|
||||
}
|
||||
|
||||
cartridge_LoadHighScoreCart();
|
||||
prosystem_cycles = sally_ExecuteRES( );
|
||||
prosystem_active = true;
|
||||
}
|
||||
}
|
||||
uint32 bg32 = 0;
|
||||
// ----------------------------------------------------------------------------
|
||||
// ExecuteFrame
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void prosystem_ExecuteFrame(const byte* input)
|
||||
{
|
||||
static byte last_background = 254;
|
||||
extern int gTotalAtariFrames;
|
||||
extern word *framePtr;
|
||||
bool bRenderScanline = false;
|
||||
|
||||
gTotalAtariFrames++;
|
||||
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
bg32 = memory_ram[BACKGRND] | (memory_ram[BACKGRND] << 8) | (memory_ram[BACKGRND]<<16) | (memory_ram[BACKGRND]<<24);
|
||||
last_background = memory_ram[BACKGRND];
|
||||
}
|
||||
cycles = maria_RenderScanline( );
|
||||
}
|
||||
|
||||
if(cartridge_cycle_stealing)
|
||||
{
|
||||
prosystem_cycles += cycles;
|
||||
if(riot_timing) riot_UpdateTimer( cycles >> 2 );
|
||||
}
|
||||
|
||||
sally_Execute(CYCLES_PER_SCANLINE);
|
||||
tia_Process(2);
|
||||
if(cartridge_pokey) pokey_Process(2);
|
||||
}
|
||||
}
|
||||
|
||||
byte *loc_buffer = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// 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.
|
||||
// Save
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void prosystem_ExecuteFrame(const byte * input)
|
||||
bool prosystem_Save(char * filename, bool compress)
|
||||
{
|
||||
extern u16 gTotalAtariFrames;
|
||||
extern word * framePtr;
|
||||
extern uint maria_cycles;
|
||||
|
||||
gTotalAtariFrames++;
|
||||
bRenderFrame = 0;
|
||||
if(strlen(filename) == 0) {
|
||||
#if 0
|
||||
logger_LogError("Filename is invalid.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
riot_SetInput(input);
|
||||
if (! loc_buffer) loc_buffer = (byte *)malloc(33000 * sizeof(byte));
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Handle the VERTICAL BLANK area first... speeds up processing below...
|
||||
// ---------------------------------------------------------------------
|
||||
memory_ram[MSTAT] = 128; // Into the Vertical Blank...
|
||||
#if 0
|
||||
logger_LogInfo("Saving game state to file " + filename + ".");
|
||||
#endif
|
||||
|
||||
uint size = 0;
|
||||
|
||||
uint index;
|
||||
for(index = 0; index < 16; index++) {
|
||||
loc_buffer[size + index] = PRO_SYSTEM_STATE_HEADER[index];
|
||||
}
|
||||
size += 16;
|
||||
|
||||
loc_buffer[size++] = 1;
|
||||
for(index = 0; index < 4; index++) {
|
||||
loc_buffer[size + index] = 0;
|
||||
}
|
||||
size += 4;
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// 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;
|
||||
for(index = 0; index < 32; index++) {
|
||||
loc_buffer[size + index] = cartridge_digest[index];
|
||||
}
|
||||
size += 32;
|
||||
|
||||
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);
|
||||
loc_buffer[size++] = sally_a;
|
||||
loc_buffer[size++] = sally_x;
|
||||
loc_buffer[size++] = sally_y;
|
||||
loc_buffer[size++] = sally_p;
|
||||
loc_buffer[size++] = sally_s;
|
||||
loc_buffer[size++] = sally_pc.b.l;
|
||||
loc_buffer[size++] = sally_pc.b.h;
|
||||
loc_buffer[size++] = cartridge_bank;
|
||||
|
||||
maria_RenderScanlineTOP();
|
||||
for(index = 0; index < 16384; index++) {
|
||||
loc_buffer[size + index] = memory_ram[index];
|
||||
}
|
||||
size += 16384;
|
||||
|
||||
if(cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) {
|
||||
for(index = 0; index < 16384; index++) {
|
||||
loc_buffer[size + index] = memory_ram[16384 + index];
|
||||
}
|
||||
size += 16384;
|
||||
}
|
||||
|
||||
if(!compress) {
|
||||
FILE* file = fopen(filename, "wb");
|
||||
if(file == NULL) {
|
||||
#if 0
|
||||
logger_LogError("Failed to open the file " + filename + " for writing.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fwrite(loc_buffer, 1, size, file) != size) {
|
||||
fclose(file);
|
||||
#if 0
|
||||
logger_LogError("Failed to write the save state data to the file " + filename + ".", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
else {
|
||||
if(!archive_Compress(filename, "Save.sav", loc_buffer, size)) {
|
||||
#if 0
|
||||
logger_LogError("Failed to compress the save state data to the file " + filename + ".", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool prosystem_Load(char * filename) {
|
||||
|
||||
sally_Execute(CYCLES_PER_SCANLINE);
|
||||
if(strlen(filename) == 0) {
|
||||
#if 0
|
||||
logger_LogError("Filename is invalid.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
if (! loc_buffer) loc_buffer = (byte *)malloc(33000 * sizeof(byte));
|
||||
|
||||
#if 0
|
||||
logger_LogInfo("Loading game state from file " + filename + ".");
|
||||
#endif
|
||||
|
||||
uint size = archive_GetUncompressedFileSize(filename);
|
||||
if(size == 0) {
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
#if 0
|
||||
logger_LogError("Failed to open the file " + filename + " for reading.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 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
|
||||
fseek(file, 0, SEEK_END);
|
||||
#if 0
|
||||
if(fseek(file, 0, SEEK_END)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the end of the file.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
#if 0
|
||||
if(fseek(file, 0, SEEK_SET)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the size of the file.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(size != 16445 && size != 32829) {
|
||||
fclose(file);
|
||||
#if 0
|
||||
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
fread(loc_buffer, 1, size, file);
|
||||
#if 0
|
||||
if(fread(loc_buffer, 1, size, file) != size && ferror(file)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to read the file data.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
fclose(file);
|
||||
}
|
||||
else if(size == 16445 || size == 32829) {
|
||||
archive_Uncompress(filename, loc_buffer, size);
|
||||
}
|
||||
else {
|
||||
#if 0
|
||||
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
uint offset = 0;
|
||||
uint index;
|
||||
for(index = 0; index < 16; index++) {
|
||||
if(loc_buffer[offset + index] != PRO_SYSTEM_STATE_HEADER[index]) {
|
||||
#if 0
|
||||
logger_LogError("File is not a valid ProSystem save state.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
offset += 16;
|
||||
|
||||
for(index = 0; index < 4; index++) {
|
||||
}
|
||||
offset += 4;
|
||||
|
||||
prosystem_Reset( );
|
||||
|
||||
char digest[33] = {0};
|
||||
for(index = 0; index < 32; index++) {
|
||||
digest[index] = loc_buffer[offset + index];
|
||||
}
|
||||
offset += 32;
|
||||
if (strcmp((const char*)cartridge_digest,digest)) {
|
||||
//if(cartridge_digest != std::string(digest)) {
|
||||
#if 0
|
||||
logger_LogError("Load state digest [" + std::string(digest) + "] does not match loaded cartridge digest [" + cartridge_digest + "].", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
sally_a = loc_buffer[offset++];
|
||||
sally_x = loc_buffer[offset++];
|
||||
sally_y = loc_buffer[offset++];
|
||||
sally_p = loc_buffer[offset++];
|
||||
sally_s = loc_buffer[offset++];
|
||||
sally_pc.b.l = loc_buffer[offset++];
|
||||
sally_pc.b.h = loc_buffer[offset++];
|
||||
|
||||
cartridge_StoreBank(loc_buffer[offset++]);
|
||||
|
||||
for(index = 0; index < 16384; index++) {
|
||||
memory_ram[index] = loc_buffer[offset + index];
|
||||
}
|
||||
offset += 16384;
|
||||
|
||||
if(cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) {
|
||||
if(size != 32829) {
|
||||
#if 0
|
||||
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
for(index = 0; index < 16384; index++) {
|
||||
memory_ram[16384 + index] = loc_buffer[offset + index];
|
||||
}
|
||||
offset += 16384;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pause
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Pause(bool pause) {
|
||||
if(prosystem_active) {
|
||||
prosystem_paused = pause;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Close
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Close()
|
||||
{
|
||||
cartridge_Release();
|
||||
maria_Reset();
|
||||
maria_Clear();
|
||||
memory_Reset();
|
||||
tia_Reset();
|
||||
tia_Clear();
|
||||
void prosystem_Close( ) {
|
||||
prosystem_active = false;
|
||||
prosystem_paused = false;
|
||||
cartridge_Release( );
|
||||
maria_Reset( );
|
||||
maria_Clear( );
|
||||
memory_Reset( );
|
||||
tia_Reset( );
|
||||
tia_Clear( );
|
||||
}
|
||||
|
|
|
@ -28,37 +28,35 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "Equates.h"
|
||||
#include "Bios.h"
|
||||
#include "Cartridge.h"
|
||||
#include "HighScore.h"
|
||||
#include "Maria.h"
|
||||
#include "Memory.h"
|
||||
#include "Region.h"
|
||||
#include "Riot.h"
|
||||
#include "Sally.h"
|
||||
#include "Archive.h"
|
||||
#include "Tia.h"
|
||||
#include "Pokey.h"
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
#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[];
|
||||
extern u8 isDS_LITE;
|
||||
extern u8 bSkipBIOS;
|
||||
|
||||
// Difficulty switches...
|
||||
#define DIFF_A 0
|
||||
#define DIFF_B 1
|
||||
// The number of cycles per scan line
|
||||
#define CYCLES_PER_SCANLINE 454
|
||||
|
||||
extern void prosystem_Reset( );
|
||||
extern void prosystem_ExecuteFrame(const byte* input);
|
||||
extern bool prosystem_Save(char* filename, bool compress);
|
||||
extern bool prosystem_Load(char* filename);
|
||||
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
|
||||
|
|
55
arm9/source/emu/Rect.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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;
|
||||
|
||||
/*
|
||||
uint GetArea( ) {
|
||||
return GetLength( ) * GetHeight( );
|
||||
}
|
||||
|
||||
uint GetLength( ) {
|
||||
return (right - left) + 1;
|
||||
}
|
||||
|
||||
uint GetHeight( ) {
|
||||
return (bottom - top) + 1;
|
||||
}
|
||||
*/
|
||||
} Rect ;
|
||||
|
||||
typedef Rect rect;
|
||||
#endif
|
||||
|
|
@ -20,223 +20,269 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Region.c
|
||||
// Region.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Region.h"
|
||||
#include "Database.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;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PALETTE NTSC
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
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_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
|
||||
#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_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
|
||||
};
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
extern uint sound_lenght;
|
||||
extern uint video_height;
|
||||
|
||||
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;
|
||||
tia_size = 624;
|
||||
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;
|
||||
tia_size = 524;
|
||||
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;
|
||||
|
||||
// ---------------------------------
|
||||
// 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);
|
||||
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;
|
||||
|
||||
sound_lenght = 22050 / prosystem_frequency;
|
||||
video_height = maria_visibleArea.bottom-maria_displayArea.top;
|
||||
}
|
||||
|
|
|
@ -24,23 +24,23 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#include "Riot.h"
|
||||
|
||||
uint riot_and_wsync __attribute__((section(".dtcm"))) = 0x00;
|
||||
int riot_timer __attribute__((section(".dtcm"))) = TIM64T;
|
||||
int riot_intervals __attribute__((section(".dtcm"))) = 0;
|
||||
bool riot_timing = false;
|
||||
word riot_timer = TIM64T;
|
||||
byte riot_intervals;
|
||||
|
||||
byte riot_dra __attribute__((section(".dtcm"))) = 0;
|
||||
byte riot_drb __attribute__((section(".dtcm"))) = 0;
|
||||
byte riot_dra = 0;
|
||||
byte riot_drb = 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;
|
||||
bool riot_elapsed;
|
||||
int riot_currentTime;
|
||||
word riot_clocks;
|
||||
word riot_shift=0;
|
||||
|
||||
void riot_Reset(void) {
|
||||
riot_SetDRA(0);
|
||||
riot_SetDRB(0);
|
||||
|
||||
riot_and_wsync = 0;
|
||||
riot_timing = false;
|
||||
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
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
ITCM_CODE void riot_SetInput(const byte* input) {
|
||||
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,6 +194,55 @@ ITCM_CODE 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;
|
||||
*/
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
|
@ -225,25 +274,25 @@ void riot_SetTimer(word timer, byte intervals)
|
|||
case T1024T:
|
||||
riot_clocks = 1024;
|
||||
riot_shift = 10;
|
||||
riot_and_wsync |= 2;
|
||||
riot_timing = true;
|
||||
break;
|
||||
case TIM1T:
|
||||
riot_clocks = 1;
|
||||
riot_shift = 0;
|
||||
riot_and_wsync |= 2;
|
||||
riot_timing = true;
|
||||
break;
|
||||
case TIM8T:
|
||||
riot_clocks = 8;
|
||||
riot_shift = 3;
|
||||
riot_and_wsync |= 2;
|
||||
riot_timing = true;
|
||||
break;
|
||||
case TIM64T:
|
||||
riot_clocks = 64;
|
||||
riot_shift = 6;
|
||||
riot_and_wsync |= 2;
|
||||
riot_timing = true;
|
||||
break;
|
||||
}
|
||||
if(riot_and_wsync) {
|
||||
if(riot_timing) {
|
||||
riot_currentTime = riot_clocks * intervals;
|
||||
riot_elapsed = false;
|
||||
}
|
||||
|
@ -252,7 +301,7 @@ void riot_SetTimer(word timer, byte intervals)
|
|||
// ----------------------------------------------------------------------------
|
||||
// UpdateTimer
|
||||
// ----------------------------------------------------------------------------
|
||||
ITCM_CODE void inline riot_UpdateTimer(byte cycles)
|
||||
void inline riot_UpdateTimer(byte cycles)
|
||||
{
|
||||
riot_currentTime -= cycles;
|
||||
if(!riot_elapsed && riot_currentTime > 0)
|
||||
|
@ -270,7 +319,7 @@ ITCM_CODE void inline riot_UpdateTimer(byte cycles)
|
|||
else
|
||||
{
|
||||
memory_ram[INTIM] = 0;
|
||||
riot_and_wsync &= 0xFD;
|
||||
riot_timing = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -37,10 +37,9 @@ 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 uint riot_and_wsync;
|
||||
extern int riot_timer;
|
||||
extern int riot_intervals;
|
||||
extern u32 snes_adaptor;
|
||||
extern bool riot_timing;
|
||||
extern word riot_timer;
|
||||
extern byte riot_intervals;
|
||||
extern void riot_SetDRA(byte data);
|
||||
extern void riot_SetDRB(byte data);
|
||||
|
||||
|
|
|
@ -31,27 +31,17 @@
|
|||
#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 uint sally_p;
|
||||
extern uint sally_s;
|
||||
extern bool wsync_happened;
|
||||
extern byte sally_p;
|
||||
extern byte sally_s;
|
||||
extern pair sally_pc;
|
||||
|
||||
extern void sally_Execute(unsigned int cycles );
|
||||
|
||||
|
|
30
arm9/source/emu/Sound.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
// 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"
|
||||
|
||||
uint sound_lenght;
|
||||
|
||||
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
|
||||
}
|
39
arm9/source/emu/Sound.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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 uint sound_lenght;
|
||||
|
||||
extern unsigned char sound_buffer[SNDLENGTH]; // Sound buffer
|
||||
|
||||
extern bool sound_Store();
|
||||
extern void processSound(register unsigned char *buffer);
|
||||
|
||||
#endif
|
|
@ -1,252 +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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// TiaSound is Copyright(c) 1997 by Ron Fries
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of version 2 of the GNU Library General Public License
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This library 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 Library
|
||||
// General Public License for more details.
|
||||
// To obtain a copy of the GNU Library General Public License, write to the
|
||||
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// Any permitted reproduction of these routines, in whole or in part, must
|
||||
// bear this legend.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tia.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Tia.h"
|
||||
|
||||
#define TIA_POLY4_SIZE 15
|
||||
#define TIA_POLY5_SIZE 31
|
||||
#define TIA_POLY9_SIZE 511
|
||||
|
||||
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 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]]))
|
||||
{
|
||||
if(tia_audc[0] & 4)
|
||||
{
|
||||
tia_volume[0] = (!tia_volume[0])? tia_audv[0]: 0;
|
||||
}
|
||||
else if(tia_audc[0] & 8)
|
||||
{
|
||||
if(tia_audc[0] == 8)
|
||||
{
|
||||
tia_poly9Cntr[0] = (tia_poly9Cntr[0]+1) % TIA_POLY9_SIZE;
|
||||
tia_volume[0] = (TIA_POLY9[tia_poly9Cntr[0]])? tia_audv[0]: 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_volume[0] = (TIA_POLY5[tia_poly5Cntr[0]])? tia_audv[0]: 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_poly4Cntr[0] = (tia_poly4Cntr[0] + 1) % TIA_POLY4_SIZE;
|
||||
tia_volume[0] = (TIA_POLY4[tia_poly4Cntr[0]])? tia_audv[0]: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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]]))
|
||||
{
|
||||
if(tia_audc[1] & 4)
|
||||
{
|
||||
tia_volume[1] = (!tia_volume[1])? tia_audv[1]: 0;
|
||||
}
|
||||
else if(tia_audc[1] & 8)
|
||||
{
|
||||
if(tia_audc[1] == 8)
|
||||
{
|
||||
tia_poly9Cntr[1] = (tia_poly9Cntr[1]+1) % TIA_POLY9_SIZE;
|
||||
tia_volume[1] = (TIA_POLY9[tia_poly9Cntr[1]])? tia_audv[1]: 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_volume[1] = (TIA_POLY5[tia_poly5Cntr[1]])? tia_audv[1]: 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_poly4Cntr[1] = (tia_poly4Cntr[1] + 1) % TIA_POLY4_SIZE;
|
||||
tia_volume[1] = (TIA_POLY4[tia_poly4Cntr[1]])? tia_audv[1]: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_Reset( ) {
|
||||
uint index;
|
||||
|
||||
tiaBufIdx = 0;
|
||||
for(index = 0; index < 2; index++) {
|
||||
tia_volume[index] = 0;
|
||||
tia_counterMax[index] = 0;
|
||||
tia_counter[index] = 0;
|
||||
tia_audc[index] = 0;
|
||||
tia_audf[index] = 0;
|
||||
tia_audv[index] = 0;
|
||||
tia_poly4Cntr[index] = 0;
|
||||
tia_poly5Cntr[index] = 0;
|
||||
tia_poly9Cntr[index] = 0;
|
||||
}
|
||||
tia_Clear( );
|
||||
tia_wait = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Clear
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_Clear( ) {
|
||||
uint index;
|
||||
for(index = 0; index < SNDLENGTH; index++) {
|
||||
tia_buffer[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Same as TIA_Process but designed for Pokey integration...
|
||||
ITCM_CODE int TIA_Sample(void)
|
||||
{
|
||||
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();
|
||||
}
|
||||
return ((int)tia_volume[0] + (int)tia_volume[1]);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Process
|
||||
// --------------------------------------------------------------------------------------
|
||||
ITCM_CODE void tia_Process(void)
|
||||
{
|
||||
u32 samp[2];
|
||||
|
||||
if (tia_wait) return;
|
||||
|
||||
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]));
|
||||
}
|
||||
|
||||
// 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]));
|
||||
}
|
|
@ -40,15 +40,12 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
#ifndef TIA_H
|
||||
#define TIA_H
|
||||
#define TIA_BUFFER_SIZE 624
|
||||
|
||||
#include "Equates.h"
|
||||
|
||||
#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];
|
||||
|
@ -56,40 +53,10 @@ 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(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
extern void tia_Process(uint length);
|
||||
extern byte tia_buffer[TIA_BUFFER_SIZE];
|
||||
extern uint tia_size;
|
||||
|
||||
#endif
|
||||
|
|
248
arm9/source/emu/Tia.itcm.c
Normal file
|
@ -0,0 +1,248 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / 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.
|
||||
// ----------------------------------------------------------------------------
|
||||
// TiaSound is Copyright(c) 1997 by Ron Fries
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of version 2 of the GNU Library General Public License
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This library 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 Library
|
||||
// General Public License for more details.
|
||||
// To obtain a copy of the GNU Library General Public License, write to the
|
||||
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// Any permitted reproduction of these routines, in whole or in part, must
|
||||
// bear this legend.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tia.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Tia.h"
|
||||
#define TIA_POLY4_SIZE 15
|
||||
#define TIA_POLY5_SIZE 31
|
||||
#define TIA_POLY9_SIZE 511
|
||||
|
||||
byte tia_buffer[TIA_BUFFER_SIZE] = {0};
|
||||
uint tia_size = 524;
|
||||
extern int debug[];
|
||||
|
||||
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 uint tia_poly4Cntr[2] = {0};
|
||||
static uint tia_poly5Cntr[2] = {0};
|
||||
static uint tia_poly9Cntr[2] = {0};
|
||||
static uint tia_soundCntr = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ProcessChannel
|
||||
// ----------------------------------------------------------------------------
|
||||
static void tia_ProcessChannel(byte channel)
|
||||
{
|
||||
tia_poly5Cntr[channel] = (tia_poly5Cntr[channel] + 1) % TIA_POLY5_SIZE;
|
||||
if(((tia_audc[channel] & 2) == 0) || (((tia_audc[channel] & 1) == 0) && TIA_DIV31[tia_poly5Cntr[channel]]) || (((tia_audc[channel] & 1) == 1) && TIA_POLY5[tia_poly5Cntr[channel]]))
|
||||
{
|
||||
if(tia_audc[channel] & 4)
|
||||
{
|
||||
tia_volume[channel] = (!tia_volume[channel])? tia_audv[channel]: 0;
|
||||
}
|
||||
else if(tia_audc[channel] & 8)
|
||||
{
|
||||
if(tia_audc[channel] == 8)
|
||||
{
|
||||
tia_poly9Cntr[channel] = (tia_poly9Cntr[channel]+1) % TIA_POLY9_SIZE;
|
||||
tia_volume[channel] = (TIA_POLY9[tia_poly9Cntr[channel]])? tia_audv[channel]: 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_volume[channel] = (TIA_POLY5[tia_poly5Cntr[channel]])? tia_audv[channel]: 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tia_poly4Cntr[channel] = (tia_poly4Cntr[channel] + 1) % TIA_POLY4_SIZE;
|
||||
tia_volume[channel] = (TIA_POLY4[tia_poly4Cntr[channel]])? tia_audv[channel]: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_Reset( ) {
|
||||
uint index;
|
||||
|
||||
tia_soundCntr = 0;
|
||||
for(index = 0; index < 2; index++) {
|
||||
tia_volume[index] = 0;
|
||||
tia_counterMax[index] = 0;
|
||||
tia_counter[index] = 0;
|
||||
tia_audc[index] = 0;
|
||||
tia_audf[index] = 0;
|
||||
tia_audv[index] = 0;
|
||||
tia_poly4Cntr[index] = 0;
|
||||
tia_poly5Cntr[index] = 0;
|
||||
tia_poly9Cntr[index] = 0;
|
||||
}
|
||||
tia_Clear( );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Clear
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_Clear( ) {
|
||||
uint index;
|
||||
for(index = 0; index < TIA_BUFFER_SIZE; index++) {
|
||||
tia_buffer[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Process
|
||||
// --------------------------------------------------------------------------------------
|
||||
void tia_Process(uint length)
|
||||
{
|
||||
static int sound_sample_150pct=0;
|
||||
uint index;
|
||||
for(index = 0; index < length; index++)
|
||||
{
|
||||
if(tia_counter[0] > 1)
|
||||
{
|
||||
tia_counter[0]--;
|
||||
}
|
||||
else if(tia_counter[0] == 1)
|
||||
{
|
||||
tia_counter[0] = tia_counterMax[0];
|
||||
tia_ProcessChannel(0);
|
||||
}
|
||||
if(tia_counter[1] > 1)
|
||||
{
|
||||
tia_counter[1]--;
|
||||
}
|
||||
else if(tia_counter[1] == 1)
|
||||
{
|
||||
tia_counter[1] = tia_counterMax[1];
|
||||
tia_ProcessChannel(1);
|
||||
}
|
||||
// We sample 50% more than we output... helps _slightly_ with sound quality...
|
||||
if (sound_sample_150pct == 0 || sound_sample_150pct == 1)
|
||||
{
|
||||
tia_buffer[tia_soundCntr] = ((tia_volume[0] + tia_volume[1])) + 128;
|
||||
tia_soundCntr = (tia_soundCntr+1) % tia_size;
|
||||
} else index--;
|
||||
sound_sample_150pct = (sound_sample_150pct+1) % 3;
|
||||
}
|
||||
}
|
|
@ -3,10 +3,21 @@
|
|||
|
||||
#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
|
||||
|
|
177
arm9/source/emu/zip/ioapi.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
/* ioapi.c -- IO base function header for compress/uncompress .zip
|
||||
files using zlib + zip or unzip API
|
||||
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zlib.h"
|
||||
#include "ioapi.h"
|
||||
|
||||
|
||||
|
||||
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
|
||||
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_END
|
||||
#define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
voidpf ZCALLBACK fopen_file_func OF((
|
||||
voidpf opaque,
|
||||
const char* filename,
|
||||
int mode));
|
||||
|
||||
uLong ZCALLBACK fread_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream,
|
||||
void* buf,
|
||||
uLong size));
|
||||
|
||||
uLong ZCALLBACK fwrite_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream,
|
||||
const void* buf,
|
||||
uLong size));
|
||||
|
||||
long ZCALLBACK ftell_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream));
|
||||
|
||||
long ZCALLBACK fseek_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream,
|
||||
uLong offset,
|
||||
int origin));
|
||||
|
||||
int ZCALLBACK fclose_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream));
|
||||
|
||||
int ZCALLBACK ferror_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream));
|
||||
|
||||
|
||||
voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
|
||||
voidpf opaque;
|
||||
const char* filename;
|
||||
int mode;
|
||||
{
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
|
||||
mode_fopen = "rb";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||
mode_fopen = "r+b";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||
mode_fopen = "wb";
|
||||
|
||||
if ((filename!=NULL) && (mode_fopen != NULL))
|
||||
file = fopen(filename, mode_fopen);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
void* buf;
|
||||
uLong size;
|
||||
{
|
||||
uLong ret;
|
||||
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
const void* buf;
|
||||
uLong size;
|
||||
{
|
||||
uLong ret;
|
||||
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long ZCALLBACK ftell_file_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
long ret;
|
||||
ret = ftell((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
uLong offset;
|
||||
int origin;
|
||||
{
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
switch (origin)
|
||||
{
|
||||
case ZLIB_FILEFUNC_SEEK_CUR :
|
||||
fseek_origin = SEEK_CUR;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END :
|
||||
fseek_origin = SEEK_END;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET :
|
||||
fseek_origin = SEEK_SET;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
ret = 0;
|
||||
fseek((FILE *)stream, offset, fseek_origin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZCALLBACK fclose_file_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
int ret;
|
||||
ret = fclose((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZCALLBACK ferror_file_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
int ret;
|
||||
ret = ferror((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_fopen_filefunc (pzlib_filefunc_def)
|
||||
zlib_filefunc_def* pzlib_filefunc_def;
|
||||
{
|
||||
pzlib_filefunc_def->zopen_file = fopen_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
pzlib_filefunc_def->ztell_file = ftell_file_func;
|
||||
pzlib_filefunc_def->zseek_file = fseek_file_func;
|
||||
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||
pzlib_filefunc_def->opaque = NULL;
|
||||
}
|
75
arm9/source/emu/zip/ioapi.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* ioapi.h -- IO base function header for compress/uncompress .zip
|
||||
files using zlib + zip or unzip API
|
||||
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
*/
|
||||
|
||||
#ifndef _ZLIBIOAPI_H
|
||||
#define _ZLIBIOAPI_H
|
||||
|
||||
|
||||
#define ZLIB_FILEFUNC_SEEK_CUR (1)
|
||||
#define ZLIB_FILEFUNC_SEEK_END (2)
|
||||
#define ZLIB_FILEFUNC_SEEK_SET (0)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_READ (1)
|
||||
#define ZLIB_FILEFUNC_MODE_WRITE (2)
|
||||
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
|
||||
#define ZLIB_FILEFUNC_MODE_CREATE (8)
|
||||
|
||||
|
||||
#ifndef ZCALLBACK
|
||||
|
||||
#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
|
||||
#define ZCALLBACK CALLBACK
|
||||
#else
|
||||
#define ZCALLBACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
|
||||
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
|
||||
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
|
||||
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
|
||||
|
||||
typedef struct zlib_filefunc_def_s
|
||||
{
|
||||
open_file_func zopen_file;
|
||||
read_file_func zread_file;
|
||||
write_file_func zwrite_file;
|
||||
tell_file_func ztell_file;
|
||||
seek_file_func zseek_file;
|
||||
close_file_func zclose_file;
|
||||
testerror_file_func zerror_file;
|
||||
voidpf opaque;
|
||||
} zlib_filefunc_def;
|
||||
|
||||
|
||||
|
||||
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
|
||||
#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
|
||||
#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
|
||||
#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
285
arm9/source/emu/zip/miniunz.c
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
# include <limits.h>
|
||||
|
||||
#include "unzip.h"
|
||||
#include "global.h"
|
||||
|
||||
#define CASESENSITIVITY (0)
|
||||
#define WRITEBUFFERSIZE (8192)
|
||||
#define MAXFILENAME (256)
|
||||
|
||||
#ifndef LINUX_MODE
|
||||
char *
|
||||
strcasestr (const char *s1, const char *s2)
|
||||
{
|
||||
char *tmps1 = (char *) strupr (strdup (s1));
|
||||
char *tmps2 = (char *) strupr (strdup (s2));
|
||||
|
||||
char *result = strstr (tmps1, tmps2);
|
||||
|
||||
free (tmps1);
|
||||
free (tmps2);
|
||||
|
||||
return result;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
static char possible_filename_in_zip[MAX_PATH];
|
||||
|
||||
/*!
|
||||
* find_possible_filename_in_zip : Look whether the given archive contains a rom
|
||||
* @param zipfilename Name of the archive file in zip format in which to search for a rom
|
||||
* @return NULL in case of error or no rom found else a pointer to a statically allocated
|
||||
* storage containing the filename found inside
|
||||
*/
|
||||
char *
|
||||
find_possible_filename_in_zip (char *zipfilename, const char* ext)
|
||||
{
|
||||
char ext_buff[128];
|
||||
uLong i;
|
||||
unz_global_info gi;
|
||||
unzFile uf;
|
||||
int err;
|
||||
|
||||
if (zipfilename == NULL)
|
||||
return NULL;
|
||||
|
||||
strcpy(ext_buff, ext);
|
||||
|
||||
uf = unzOpen (zipfilename);
|
||||
|
||||
if (uf == NULL)
|
||||
{
|
||||
strcat (zipfilename, ".zip");
|
||||
uf = unzOpen (zipfilename);
|
||||
}
|
||||
|
||||
if (uf == NULL)
|
||||
return NULL;
|
||||
|
||||
err = unzGetGlobalInfo (uf, &gi);
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
unzClose( uf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < gi.number_entry; i++)
|
||||
{
|
||||
char filename_inzip[256];
|
||||
unz_file_info file_info;
|
||||
|
||||
err = unzGetCurrentFileInfo (uf, &file_info, filename_inzip,
|
||||
sizeof (filename_inzip), NULL, 0, NULL, 0);
|
||||
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
unzClose( uf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* strtok_ext = ext_buff;
|
||||
const char* scan_ext;
|
||||
while ( (scan_ext = strtok( strtok_ext, ".")) != 0) {
|
||||
strtok_ext = 0;
|
||||
if (strcasestr(filename_inzip, scan_ext))
|
||||
{
|
||||
strncpy (possible_filename_in_zip, filename_inzip, MAX_PATH);
|
||||
unzClose( uf );
|
||||
return possible_filename_in_zip;
|
||||
}
|
||||
}
|
||||
|
||||
if ((i + 1) < gi.number_entry)
|
||||
{
|
||||
err = unzGoToNextFile (uf);
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
unzClose( uf );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unzClose( uf );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* do_extract_currentfile_in_memory : Extract the current pointed file in the zip archive into a buffer
|
||||
* @param uf the archive file handle
|
||||
* @param unzipped_size a pointer to the size of the unzipped data, it is filled by this function for caller
|
||||
* @return uncompressed data as pointer, to be freed by caller or NULL in case of problem
|
||||
*/
|
||||
static char *
|
||||
do_extract_currentfile_in_memory (unzFile uf, size_t * unzipped_size)
|
||||
{
|
||||
char filename_inzip[256];
|
||||
char *filename_withoutpath;
|
||||
char *p;
|
||||
int err = UNZ_OK;
|
||||
FILE *fout = NULL;
|
||||
void *buf;
|
||||
uInt size_buf;
|
||||
unz_file_info file_info;
|
||||
char *return_value = NULL;
|
||||
|
||||
err = unzGetCurrentFileInfo (uf, &file_info, filename_inzip,
|
||||
sizeof (filename_inzip), NULL, 0, NULL, 0);
|
||||
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
//Log ("error %d with zipfile in unzGetCurrentFileInfo\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_buf = WRITEBUFFERSIZE;
|
||||
buf = (void *) malloc (size_buf);
|
||||
if (buf == NULL)
|
||||
{
|
||||
//Log ("Error allocating memory\n");
|
||||
return UNZ_INTERNALERROR;
|
||||
}
|
||||
|
||||
p = filename_withoutpath = filename_inzip;
|
||||
while ((*p) != '\0')
|
||||
{
|
||||
if (((*p) == '/') || ((*p) == '\\'))
|
||||
filename_withoutpath = p + 1;
|
||||
p++;
|
||||
}
|
||||
|
||||
if ((*filename_withoutpath) != '\0')
|
||||
{
|
||||
const char *write_filename;
|
||||
int skip = 0;
|
||||
|
||||
write_filename = filename_withoutpath;
|
||||
|
||||
err = unzOpenCurrentFile (uf);
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
//Log ("error %d with zipfile in unzOpenCurrentFile\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*unzipped_size = 0;
|
||||
|
||||
do
|
||||
{
|
||||
err = unzReadCurrentFile (uf, buf, size_buf);
|
||||
if (err < 0)
|
||||
{
|
||||
//Log ("error %d with zipfile in unzReadCurrentFile\n", err);
|
||||
break;
|
||||
}
|
||||
if (err > 0)
|
||||
{
|
||||
*unzipped_size += err;
|
||||
return_value = realloc (return_value, *unzipped_size);
|
||||
if (return_value == NULL)
|
||||
{
|
||||
err = UNZ_ERRNO;
|
||||
break;
|
||||
}
|
||||
memcpy (return_value + *unzipped_size - err, buf, err);
|
||||
}
|
||||
}
|
||||
while (err > 0);
|
||||
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
//Log ("Error %s with zipfile in uncompressing\n", strerror (errno));
|
||||
}
|
||||
|
||||
err = unzCloseCurrentFile (uf);
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
//Log ("error %d with zipfile in unzCloseCurrentFile\n", err);
|
||||
}
|
||||
}
|
||||
|
||||
free (buf);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* do_extract_onefile_in_memory : Extract an archived file into a buffer
|
||||
* @param uf Handle to the archive in ip format in which to read data
|
||||
* @param filename Name of the file archived in the zip file the data of which we want
|
||||
* @param unzipped_size Pointer to the size of the extracted data
|
||||
* @return NULL in case of problem or a pointer to the archived file content. It is allocated
|
||||
*/
|
||||
static char *
|
||||
do_extract_onefile_in_memory (unzFile uf, const char *filename,
|
||||
size_t * unzipped_size)
|
||||
{
|
||||
if (unzLocateFile (uf, filename, CASESENSITIVITY) != UNZ_OK)
|
||||
{
|
||||
//Log ("file %s not found in the zipfile\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return do_extract_currentfile_in_memory (uf, unzipped_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* extract_file_in_memory : Extract an archived file into a buffer
|
||||
* @param zipfilename Name of the archive in zip format in which to read data
|
||||
* @param archivedfile Name of the file archived in the zip file the data of which we want
|
||||
* @param unzipped_size Pointer to the size of the extracted data
|
||||
* @return NULL in case of problem or a pointer to the archived file content. It is allocated
|
||||
* dynamically and needs to be explicitely freed
|
||||
*/
|
||||
extern char *
|
||||
extract_file_in_memory (char *zipfilename, char *archivedfile, size_t * unzipped_size)
|
||||
{
|
||||
unzFile uf;
|
||||
int err;
|
||||
char *return_value;
|
||||
|
||||
if (zipfilename == NULL)
|
||||
return NULL;
|
||||
|
||||
uf = unzOpen (zipfilename);
|
||||
|
||||
if (uf == NULL)
|
||||
{
|
||||
strcat (zipfilename, ".zip");
|
||||
uf = unzOpen (zipfilename);
|
||||
}
|
||||
|
||||
if (uf == NULL)
|
||||
return NULL;
|
||||
|
||||
return_value =
|
||||
do_extract_onefile_in_memory (uf, archivedfile, unzipped_size);
|
||||
|
||||
unzCloseCurrentFile (uf);
|
||||
unzClose(uf);
|
||||
|
||||
return return_value;
|
||||
}
|
26
arm9/source/emu/zip/miniunz.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef MINIUNZ_H
|
||||
#define MINIUNZ_H
|
||||
|
||||
//! Look for possible filename in zip archive
|
||||
char *find_possible_filename_in_zip (char *zipfilename, const char* extstr);
|
||||
|
||||
//! Extract file content from zip archive
|
||||
int extract_file_in_memory (char *zipfilename, char *archivedfile,
|
||||
size_t * unzipped_size);
|
||||
|
||||
#endif
|
1299
arm9/source/emu/zip/unzip.c
Normal file
275
arm9/source/emu/zip/unzip.h
Normal file
|
@ -0,0 +1,275 @@
|
|||
/* unzip.h -- IO for uncompress .zip files using zlib
|
||||
Version 0.15 beta, Mar 19th, 1998,
|
||||
|
||||
Copyright (C) 1998 Gilles Vollant
|
||||
|
||||
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
|
||||
WinZip, InfoZip tools and compatible.
|
||||
Encryption and multi volume ZipFile (span) are not supported.
|
||||
Old compressions used by old PKZip 1.x are not supported
|
||||
|
||||
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
|
||||
CAN CHANGE IN FUTURE VERSION !!
|
||||
I WAIT FEEDBACK at mail info@winimage.com
|
||||
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
|
||||
|
||||
Condition of use and distribution are the same than zlib :
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
*/
|
||||
/* for more info about .ZIP format, see
|
||||
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
|
||||
PkWare has also a specification at :
|
||||
ftp://ftp.pkware.com/probdesc.zip */
|
||||
|
||||
#ifndef _unz_H
|
||||
#define _unz_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||
from (void*) without cast */
|
||||
typedef struct TagunzFile__ { int unused; } unzFile__;
|
||||
typedef unzFile__ *unzFile;
|
||||
#else
|
||||
typedef voidp unzFile;
|
||||
#endif
|
||||
|
||||
|
||||
#define UNZ_OK (0)
|
||||
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
||||
#define UNZ_ERRNO (Z_ERRNO)
|
||||
#define UNZ_EOF (0)
|
||||
#define UNZ_PARAMERROR (-102)
|
||||
#define UNZ_BADZIPFILE (-103)
|
||||
#define UNZ_INTERNALERROR (-104)
|
||||
#define UNZ_CRCERROR (-105)
|
||||
|
||||
/* tm_unz contain date/time info */
|
||||
typedef struct tm_unz_s
|
||||
{
|
||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
||||
uInt tm_mday; /* day of the month - [1,31] */
|
||||
uInt tm_mon; /* months since January - [0,11] */
|
||||
uInt tm_year; /* years - [1980..2044] */
|
||||
} tm_unz;
|
||||
|
||||
/* unz_global_info structure contain global data about the ZIPfile
|
||||
These data comes from the end of central dir */
|
||||
typedef struct unz_global_info_s
|
||||
{
|
||||
uLong number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
uLong size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info;
|
||||
|
||||
|
||||
/* unz_file_info contain information about a file in the zipfile */
|
||||
typedef struct unz_file_info_s
|
||||
{
|
||||
uLong version; /* version made by 2 bytes */
|
||||
uLong version_needed; /* version needed to extract 2 bytes */
|
||||
uLong flag; /* general purpose bit flag 2 bytes */
|
||||
uLong compression_method; /* compression method 2 bytes */
|
||||
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
|
||||
uLong crc; /* crc-32 4 bytes */
|
||||
uLong compressed_size; /* compressed size 4 bytes */
|
||||
uLong uncompressed_size; /* uncompressed size 4 bytes */
|
||||
uLong size_filename; /* filename length 2 bytes */
|
||||
uLong size_file_extra; /* extra field length 2 bytes */
|
||||
uLong size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
uLong disk_num_start; /* disk number start 2 bytes */
|
||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
tm_unz tmu_date;
|
||||
} unz_file_info;
|
||||
|
||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Compare two filename (fileName1,fileName2).
|
||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
||||
or strcasecmp)
|
||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
||||
(like 1 on Unix, 2 on Windows)
|
||||
*/
|
||||
|
||||
|
||||
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
||||
/*
|
||||
Open a Zip file. path contain the full pathname (by example,
|
||||
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
|
||||
"zlib/zlib111.zip".
|
||||
If the zipfile cannot be opened (file don't exist or in not valid), the
|
||||
return value is NULL.
|
||||
Else, the return value is a unzFile Handle, usable with other function
|
||||
of this unzip package.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzClose OF((unzFile file));
|
||||
/*
|
||||
Close a ZipFile opened with unzipOpen.
|
||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
||||
unz_global_info *pglobal_info));
|
||||
/*
|
||||
Write info about the ZipFile in the *pglobal_info structure.
|
||||
No preparation of the structure is needed
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
||||
char *szComment,
|
||||
uLong uSizeBuf));
|
||||
/*
|
||||
Get the global comment string of the ZipFile, in the szComment buffer.
|
||||
uSizeBuf is the size of the szComment buffer.
|
||||
return the number of byte copied or an error code <0
|
||||
*/
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Unzip package allow you browse the directory of the zipfile */
|
||||
|
||||
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the first file.
|
||||
return UNZ_OK if there is no problem
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the next file.
|
||||
return UNZ_OK if there is no problem
|
||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
||||
const char *szFileName,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Try locate the file szFileName in the zipfile.
|
||||
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
||||
|
||||
return value :
|
||||
UNZ_OK if the file is found. It becomes the current file.
|
||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize));
|
||||
/*
|
||||
Get Info about the current file
|
||||
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
||||
the current file
|
||||
if szFileName!=NULL, the filemane string will be copied in szFileName
|
||||
(fileNameBufferSize is the size of the buffer)
|
||||
if extraField!=NULL, the extra field information will be copied in extraField
|
||||
(extraFieldBufferSize is the size of the buffer).
|
||||
This is the Central-header version of the extra field
|
||||
if szComment!=NULL, the comment string of the file will be copied in szComment
|
||||
(commentBufferSize is the size of the buffer)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
/* for reading the content of the current zipfile, you can open it, read data
|
||||
from it, and close it (you can close it before reading all the file)
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
If there is no error, the return value is UNZ_OK.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Close the file in zip opened with unzOpenCurrentFile
|
||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read bytes from the current file (opened by unzOpenCurrentFile)
|
||||
buf contain buffer where data must be copied
|
||||
len the size of buf.
|
||||
|
||||
return the number of byte copied if somes bytes are copied
|
||||
return 0 if the end of file was reached
|
||||
return <0 with error code if there is an error
|
||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
||||
*/
|
||||
|
||||
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
||||
/*
|
||||
Give the current position in uncompressed data
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzeof OF((unzFile file));
|
||||
/*
|
||||
return 1 if the end of file was reached, 0 elsewhere
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read extra field from the current file (opened by unzOpenCurrentFile)
|
||||
This is the local-header version of the extra field (sometimes, there is
|
||||
more info in the local-header version than in the central-header)
|
||||
|
||||
if buf==NULL, it return the size of the local extra field
|
||||
|
||||
if buf!=NULL, len is the size of the buffer, the extra header is copied in
|
||||
buf.
|
||||
the return value is the number of bytes copied in buf, or (if <0)
|
||||
the error code
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _unz_H */
|
1219
arm9/source/emu/zip/zip.c
Normal file
235
arm9/source/emu/zip/zip.h
Normal file
|
@ -0,0 +1,235 @@
|
|||
/* zip.h -- IO for compress .zip files using zlib
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
|
||||
This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
|
||||
WinZip, InfoZip tools and compatible.
|
||||
Multi volume ZipFile (span) are not supported.
|
||||
Encryption compatible with pkzip 2.04g only supported
|
||||
Old compressions used by old PKZip 1.x are not supported
|
||||
|
||||
For uncompress .zip file, look at unzip.h
|
||||
|
||||
|
||||
I WAIT FEEDBACK at mail info@winimage.com
|
||||
Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
|
||||
|
||||
Condition of use and distribution are the same than zlib :
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/* for more info about .ZIP format, see
|
||||
http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
|
||||
http://www.info-zip.org/pub/infozip/doc/
|
||||
PkWare has also a specification at :
|
||||
ftp://ftp.pkware.com/probdesc.zip
|
||||
*/
|
||||
|
||||
#ifndef _zip_H
|
||||
#define _zip_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIBIOAPI_H
|
||||
#include "ioapi.h"
|
||||
#endif
|
||||
|
||||
#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
|
||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||
from (void*) without cast */
|
||||
typedef struct TagzipFile__ { int unused; } zipFile__;
|
||||
typedef zipFile__ *zipFile;
|
||||
#else
|
||||
typedef voidp zipFile;
|
||||
#endif
|
||||
|
||||
#define ZIP_OK (0)
|
||||
#define ZIP_EOF (0)
|
||||
#define ZIP_ERRNO (Z_ERRNO)
|
||||
#define ZIP_PARAMERROR (-102)
|
||||
#define ZIP_BADZIPFILE (-103)
|
||||
#define ZIP_INTERNALERROR (-104)
|
||||
|
||||
#ifndef DEF_MEM_LEVEL
|
||||
# if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
# else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
# endif
|
||||
#endif
|
||||
/* default memLevel */
|
||||
|
||||
/* tm_zip contain date/time info */
|
||||
typedef struct tm_zip_s
|
||||
{
|
||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
||||
uInt tm_mday; /* day of the month - [1,31] */
|
||||
uInt tm_mon; /* months since January - [0,11] */
|
||||
uInt tm_year; /* years - [1980..2044] */
|
||||
} tm_zip;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
tm_zip tmz_date; /* date in understandable format */
|
||||
uLong dosDate; /* if dos_date == 0, tmu_date is used */
|
||||
/* uLong flag; */ /* general purpose bit flag 2 bytes */
|
||||
|
||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
} zip_fileinfo;
|
||||
|
||||
typedef const char* zipcharpc;
|
||||
|
||||
|
||||
#define APPEND_STATUS_CREATE (0)
|
||||
#define APPEND_STATUS_CREATEAFTER (1)
|
||||
#define APPEND_STATUS_ADDINZIP (2)
|
||||
|
||||
extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
|
||||
/*
|
||||
Create a zipfile.
|
||||
pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
|
||||
an Unix computer "zlib/zlib113.zip".
|
||||
if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
|
||||
will be created at the end of the file.
|
||||
(useful if the file contain a self extractor code)
|
||||
if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
|
||||
add files in existing zip (be sure you don't add file that doesn't exist)
|
||||
If the zipfile cannot be opened, the return value is NULL.
|
||||
Else, the return value is a zipFile Handle, usable with other function
|
||||
of this zip package.
|
||||
*/
|
||||
|
||||
/* Note : there is no delete function into a zipfile.
|
||||
If you want delete file into a zipfile, you must open a zipfile, and create another
|
||||
Of couse, you can use RAW reading and writing to copy the file you did not want delte
|
||||
*/
|
||||
|
||||
extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
|
||||
int append,
|
||||
zipcharpc* globalcomment,
|
||||
zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
|
||||
const char* filename,
|
||||
const zip_fileinfo* zipfi,
|
||||
const void* extrafield_local,
|
||||
uInt size_extrafield_local,
|
||||
const void* extrafield_global,
|
||||
uInt size_extrafield_global,
|
||||
const char* comment,
|
||||
int method,
|
||||
int level));
|
||||
/*
|
||||
Open a file in the ZIP for writing.
|
||||
filename : the filename in zip (if NULL, '-' without quote will be used
|
||||
*zipfi contain supplemental information
|
||||
if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
|
||||
contains the extrafield data the the local header
|
||||
if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
|
||||
contains the extrafield data the the local header
|
||||
if comment != NULL, comment contain the comment string
|
||||
method contain the compression method (0 for store, Z_DEFLATED for deflate)
|
||||
level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
|
||||
const char* filename,
|
||||
const zip_fileinfo* zipfi,
|
||||
const void* extrafield_local,
|
||||
uInt size_extrafield_local,
|
||||
const void* extrafield_global,
|
||||
uInt size_extrafield_global,
|
||||
const char* comment,
|
||||
int method,
|
||||
int level,
|
||||
int raw));
|
||||
|
||||
/*
|
||||
Same than zipOpenNewFileInZip, except if raw=1, we write raw file
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
|
||||
const char* filename,
|
||||
const zip_fileinfo* zipfi,
|
||||
const void* extrafield_local,
|
||||
uInt size_extrafield_local,
|
||||
const void* extrafield_global,
|
||||
uInt size_extrafield_global,
|
||||
const char* comment,
|
||||
int method,
|
||||
int level,
|
||||
int raw,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
const char* password,
|
||||
uLong crcForCtypting));
|
||||
|
||||
/*
|
||||
Same than zipOpenNewFileInZip2, except
|
||||
windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
|
||||
password : crypting password (NULL for no crypting)
|
||||
crcForCtypting : crc of file to compress (needed for crypting)
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
|
||||
const void* buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Write data in the zipfile
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
|
||||
/*
|
||||
Close the current file in the zipfile
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
|
||||
uLong uncompressed_size,
|
||||
uLong crc32));
|
||||
/*
|
||||
Close the current file in the zipfile, for fiel opened with
|
||||
parameter raw=1 in zipOpenNewFileInZip2
|
||||
uncompressed_size and crc32 are value for the uncompressed size
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipClose OF((zipFile file,
|
||||
const char* global_comment));
|
||||
/*
|
||||
Close the zipfile
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _zip_H */
|
|
@ -1,9 +1,7 @@
|
|||
#include <nds.h>
|
||||
#include <stdio.h>
|
||||
#include <maxmod9.h>
|
||||
|
||||
#include "a7800utils.h"
|
||||
#include "soundbank.h"
|
||||
|
||||
#include "mus_intro_wav.h"
|
||||
#include "pdev_tbg0.h"
|
||||
|
@ -17,6 +15,7 @@ void vblankIntro() {
|
|||
|
||||
// Intro with portabledev logo
|
||||
void intro_logo(void) {
|
||||
int soundId=-1;
|
||||
bool bOK;
|
||||
|
||||
// Init graphics
|
||||
|
@ -35,8 +34,6 @@ 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);
|
||||
|
@ -48,6 +45,8 @@ 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;
|
||||
|
@ -56,4 +55,5 @@ 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,40 +1,10 @@
|
|||
// =====================================================================================
|
||||
// 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)
|
||||
|
@ -58,26 +28,14 @@ int main(int argc, char **argv)
|
|||
// Intro and main screen
|
||||
intro_logo();
|
||||
dsInitScreenMain();
|
||||
emu_state = A7800_MENUINIT;
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
LoadConfig();
|
||||
|
||||
bios_check_and_load();
|
||||
etatEmu = A7800_MENUINIT;
|
||||
|
||||
//load rom file via args if a rom path is supplied
|
||||
if(argc > 1)
|
||||
{
|
||||
dsShowScreenMain(true);
|
||||
dsShowScreenMain();
|
||||
dsLoadGame(argv[1]);
|
||||
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.
|
||||
etatEmu = A7800_PLAYINIT;
|
||||
}
|
||||
|
||||
// Main loop of emulation
|
||||
|
|
|
@ -1,29 +1,3 @@
|
|||
// =====================================================================================
|
||||
// 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
|
||||
|
||||
|
|
|
@ -1,914 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// \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;
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// \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_
|
|
@ -1,6 +0,0 @@
|
|||
#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 |
84
readme.txt
Normal file
|
@ -0,0 +1,84 @@
|
|||
a7800DS
|
||||
--------------------------------------------------------------------------------
|
||||
a7800DS is an Atari ProSystem 7800 console emulator.
|
||||
To use this emulator, you must use compatibles rom with a78/bin format.
|
||||
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.
|
||||
|
||||
Missing :
|
||||
---------
|
||||
All that is not yet emulated ;)
|
||||
Need to improve speed
|
||||
|
||||
Check updates on my web site :
|
||||
http://www.portabledev.com
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
History :
|
||||
--------------------------------------------------------------------------------
|
||||
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 :
|
||||
--------------------------------------------------------------------------------
|
||||
YOU NEED PERHAPS TO PATCH THE NDS FILE WITH THE DLDI PATCH BEFORE USING IT.
|
||||
Unzip a7800DS.nds from the a7800DS.zip archive in a directory of your flash / (micro) SD
|
||||
/ MMC card.
|
||||
Put the a78/bin files where you want on your flashcard.
|
||||
|
||||
That's all, a7800DS can be use now :) !
|
||||
|
||||
When the emulator starts, click on the cartridge slot to choose a file. you are 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 : START Button
|
||||
* R : RESET Button (yes R like Reset :P)
|
||||
|
||||
Use stylus on buttons for other actions on bottom screen.
|
||||
--------------------------------------------------------------------------------
|
||||
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).
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Alekmaul
|
||||
alekmaul@portabledev.com
|
||||
http://www.portabledev.com
|
||||
--------------------------------------------------------------------------------
|
Before Width: | Height: | Size: 424 KiB |
|
@ -1,192 +0,0 @@
|
|||
; 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"
|
||||
|