Start work on Honda Oddessy2
This commit is contained in:
parent
69d0b36ca1
commit
9ff2da5265
|
@ -102,6 +102,7 @@ namespace BizHawk.Client.ApiHawk
|
||||||
case "VB":
|
case "VB":
|
||||||
case "NGP":
|
case "NGP":
|
||||||
case "DNGP":
|
case "DNGP":
|
||||||
|
case "O2":
|
||||||
return 0; // like I give a shit
|
return 0; // like I give a shit
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -340,6 +340,10 @@ namespace BizHawk.Emulation.Common
|
||||||
case ".NGC":
|
case ".NGC":
|
||||||
game.System = "NGP";
|
game.System = "NGP";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ".O2":
|
||||||
|
game.System = "O2";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.Name = Path.GetFileNameWithoutExtension(fileName)?.Replace('_', ' ');
|
game.Name = Path.GetFileNameWithoutExtension(fileName)?.Replace('_', ' ');
|
||||||
|
|
|
@ -200,6 +200,9 @@ namespace BizHawk.Emulation.Common
|
||||||
Firmware("AppleII", "DiskII", "DiskII.rom");
|
Firmware("AppleII", "DiskII", "DiskII.rom");
|
||||||
var appleII_DiskII = File("D4181C9F046AAFC3FB326B381BAAC809D9E38D16", 256, "DiskII.rom", "Disk II");
|
var appleII_DiskII = File("D4181C9F046AAFC3FB326B381BAAC809D9E38D16", 256, "DiskII.rom", "Disk II");
|
||||||
Option("AppleII", "DiskII", appleII_DiskII);
|
Option("AppleII", "DiskII", appleII_DiskII);
|
||||||
|
|
||||||
|
FirmwareAndOption("b2e1955d957a475de2411770452eff4ea19f4cee", 1024, "O2", "BIOS", "Odyssey2.bin", "Odyssey 2 Bios");
|
||||||
|
FirmwareAndOption("a6120aed50831c9c0d95dbdf707820f601d9452e", 1024, "O2", "BIOS-C52", "PhillipsC52.bin", "Phillips C52 Bios");
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds a defined firmware ID to the database
|
// adds a defined firmware ID to the database
|
||||||
|
|
|
@ -475,6 +475,8 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Consoles\Intellivision\PSG.cs" />
|
<Compile Include="Consoles\Intellivision\PSG.cs" />
|
||||||
<Compile Include="Consoles\Intellivision\STIC.cs" />
|
<Compile Include="Consoles\Intellivision\STIC.cs" />
|
||||||
|
<Compile Include="Consoles\Magnavox\LibO2Em.cs" />
|
||||||
|
<Compile Include="Consoles\Magnavox\O2Em.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.cs" />
|
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.ICodeDataLog.cs">
|
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.ICodeDataLog.cs">
|
||||||
<DependentUpon>Gambatte.cs</DependentUpon>
|
<DependentUpon>Gambatte.cs</DependentUpon>
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
using BizHawk.Common.BizInvoke;
|
||||||
|
using BizHawk.Emulation.Cores.Waterbox;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Consoles.Magnavox
|
||||||
|
{
|
||||||
|
public abstract class LibO2Em : LibWaterboxCore
|
||||||
|
{
|
||||||
|
[BizImport(CC)]
|
||||||
|
public abstract bool Init(byte[] rom, int romlen, byte[] bios, int bioslen);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
using BizHawk.Emulation.Cores.Waterbox;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Consoles.Magnavox
|
||||||
|
{
|
||||||
|
[CoreAttributes("o2em", "", true, false, "", "", false)]
|
||||||
|
public class O2Em : WaterboxCore
|
||||||
|
{
|
||||||
|
private LibO2Em _core;
|
||||||
|
|
||||||
|
[CoreConstructor("O2")]
|
||||||
|
public O2Em(CoreComm comm, byte[] rom)
|
||||||
|
:base(comm, new Configuration
|
||||||
|
{
|
||||||
|
DefaultFpsNumerator = 60,
|
||||||
|
DefaultFpsDenominator = 1,
|
||||||
|
DefaultWidth = 320,
|
||||||
|
DefaultHeight = 240,
|
||||||
|
MaxSamples = 2048,
|
||||||
|
MaxWidth = 320,
|
||||||
|
MaxHeight = 240,
|
||||||
|
SystemId = "O2"
|
||||||
|
})
|
||||||
|
{
|
||||||
|
var bios = comm.CoreFileProvider.GetFirmware("O2", "BIOS", true);
|
||||||
|
_core = PreInit<LibO2Em>(new PeRunnerOptions
|
||||||
|
{
|
||||||
|
Filename = "o2em.wbx",
|
||||||
|
SbrkHeapSizeKB = 4 * 1024,
|
||||||
|
SealedHeapSizeKB = 4 * 1024,
|
||||||
|
InvisibleHeapSizeKB = 4 * 1024,
|
||||||
|
PlainHeapSizeKB = 4 * 1024,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (!_core.Init(rom, rom.Length, bios, bios.Length))
|
||||||
|
throw new InvalidOperationException("Init() failed");
|
||||||
|
|
||||||
|
PostInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
|
||||||
|
{
|
||||||
|
return new LibWaterboxCore.FrameInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// Place your settings in this file to overwrite default and user settings.
|
||||||
|
{
|
||||||
|
"editor.tabSize": 4,
|
||||||
|
"editor.insertSpaces": false,
|
||||||
|
"editor.detectIndentation": false
|
||||||
|
}
|
|
@ -0,0 +1,316 @@
|
||||||
|
v1.18: 01/15/2007
|
||||||
|
|
||||||
|
- added the option -biosdir to define bios directory path
|
||||||
|
- added the option -romdir to define rom directory path
|
||||||
|
- added the option -help to help display
|
||||||
|
- directory search fix : When you don't have the "roms/" and/or "bios/"
|
||||||
|
directory, the program will dump core (by Walter de Jong).
|
||||||
|
- O2Launcher works now, o2em ignore roms and bios path if o2Launcher
|
||||||
|
is running.
|
||||||
|
- quad display fix: changed the way quad chars are drawn, fixes problems
|
||||||
|
in KTAA as well as score display in Black Hole and Red Baron (Soeren Gust)
|
||||||
|
- support for Soerens MegaCART bank switching (Information about
|
||||||
|
how to use this will be included in the next verison of Soerens
|
||||||
|
Bios-Documentation) (Soeren Gust)
|
||||||
|
- new feature in debugger: savevpp to make an uncompressed dump of the VPP
|
||||||
|
screen and slide data (Soeren Gust)
|
||||||
|
- dis48: fix to work under linux again (Soeren Gust)
|
||||||
|
- init_sound volume is not set to maximum (By Gunter Wambaugh)
|
||||||
|
- added makefile and options for freeBSD (By Gunter Wambaugh)
|
||||||
|
- Other minor fixes.
|
||||||
|
|
||||||
|
|
||||||
|
all the next changes were implemented by Manopac:
|
||||||
|
|
||||||
|
- added the option -s0 to redefine the system keys (see o2em.txt for usage)
|
||||||
|
- bugfix: highscore-file is only written if scoretype is set
|
||||||
|
- changed Default Stick 1 key from right <Control> to "L" to enable Fire and
|
||||||
|
movement at the same time
|
||||||
|
- two joysticks can be used now: first stick in command-line is mapped to joystick 1,
|
||||||
|
second to joystick 2 (compatible to old command line options)
|
||||||
|
- changes in debugger: status of registers is now displayed after instructions
|
||||||
|
are executed
|
||||||
|
- new features in debugger: savedatah and savedatab to save data from memory
|
||||||
|
as sourcecode ("db xxx")
|
||||||
|
- changed Default Stick 1 key from right <Control> to "L" to enable Fire
|
||||||
|
and movement at the same time
|
||||||
|
- two joysticks can be used now: first stick in command-line is mapped to
|
||||||
|
joystick 1, second to joystick 2 (compatible to old command line options)
|
||||||
|
- changes in debugger: status of registers is now displayed after
|
||||||
|
instructions are executed
|
||||||
|
- new features in debugger: savedatah and savedatab to save data from memory
|
||||||
|
as sourcecode ("db xxx")
|
||||||
|
- removed the limit that KTAA was the only 3K enabled rom (every
|
||||||
|
rom divideable by 3K is allowed now)
|
||||||
|
- dis48: added option -bios to disassemble bios (start at address 0)
|
||||||
|
- dis48: empty line after each page
|
||||||
|
- new feature to save the highscore in games (F6 to set in game)
|
||||||
|
- new feature to save/load state (F2/F3) (with command line option savefile)
|
||||||
|
- new features in debugger: savevdc and saveext to save data from Extram and VDC
|
||||||
|
- new feature in debugger: viewsprite
|
||||||
|
- new feature in debugger: bp (breakpoint) - o2em runs with output until
|
||||||
|
breakpoint is reached (bpc to clear)
|
||||||
|
- new feature in debugger: so (step over) - runs to next instruction in memory
|
||||||
|
- more explicit register display (P1 & PSW)
|
||||||
|
- fixed the "double size sprites are shifted only 1 instead of 2 pixles" bug
|
||||||
|
- new features in debugger (load / save file, change values in memory,
|
||||||
|
assemble to memory)
|
||||||
|
|
||||||
|
v1.17: 05/01/2005
|
||||||
|
|
||||||
|
- BIOS identified by CRC, to activate a specific BIOS type: -o2rom, or
|
||||||
|
-g7400, or -c52, or -jopac. The old form can be used. See O2EM.txt for more.
|
||||||
|
|
||||||
|
- Automatic identification of BIOS VP+ when the selected game is only VP+.
|
||||||
|
|
||||||
|
- Creation of the standard directories (ROMS, BIOS, VOICE) when uncompressing
|
||||||
|
O2EM archive.
|
||||||
|
|
||||||
|
- ATLANTIS, FROGGER, COMANDO NOTURNO and CATCH THE BALL now work without
|
||||||
|
graphic bugs. This correction is based on a specific patch for each game.
|
||||||
|
Thanks Rafael Cardoso for reports these bugs.
|
||||||
|
|
||||||
|
|
||||||
|
V1.16: 12/28/2004
|
||||||
|
|
||||||
|
- Fixed a slowdown in Pick Axe Pete (based on a patch by Arlindo de
|
||||||
|
Oliveira).
|
||||||
|
|
||||||
|
- Reverted back to the old palette for O2 games, while using the new
|
||||||
|
palette for Videpac Plus games (selected based on bios version in use).
|
||||||
|
|
||||||
|
|
||||||
|
V1.15: 12/12/2004
|
||||||
|
|
||||||
|
- Added support for 12kb and 16kb games. Trans American Rally+ works now.
|
||||||
|
|
||||||
|
- Added fixes to the VP+ gfx emulation made by Soeren Gust. Flashpoint
|
||||||
|
works properly now.
|
||||||
|
|
||||||
|
- Fixed a bug in the Windows-specific emulation timing code that caused
|
||||||
|
the emulator to crash when run on a Windows machine which was on for a
|
||||||
|
few days without a reboot.
|
||||||
|
|
||||||
|
- Fixed a bug in the emulation of the DAA instruction, which caused bugs
|
||||||
|
in the score of several games (Le Tresor Englouti, Cosmic Conflict, etc.).
|
||||||
|
|
||||||
|
- Fixed instruction timings (patch by Soeren)
|
||||||
|
|
||||||
|
- Modified the palette to use values calculated from the Videopac+ RGB
|
||||||
|
encoder specs by René van den Enden, instead of guessed values.
|
||||||
|
|
||||||
|
- Other minor fixes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
V1.01: 10/23/2002
|
||||||
|
|
||||||
|
- Major speed optimization.
|
||||||
|
|
||||||
|
- Implemented VDC <-> VP+ collision detection.
|
||||||
|
|
||||||
|
- On the original machines it is possible to make all VDC
|
||||||
|
colors bright by clearing P17. This affects the background and
|
||||||
|
dark grid colors. Implemented. Now the Killer Bees! intro screen
|
||||||
|
works correctly.
|
||||||
|
|
||||||
|
- Fixed the wrong color order when mixing between VP+ and VDC graphics.
|
||||||
|
Jopac Moto Crash now works. Fixed by Soeren Gust.
|
||||||
|
|
||||||
|
- Now the VBLANK pulse is visible on the T1 input. This can be used
|
||||||
|
to differentiate between PAL and NTSC.
|
||||||
|
|
||||||
|
- Other minor fixes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
V1.00: 09/12/2002
|
||||||
|
|
||||||
|
- Implemented complete Videopac+ G7400 emulation. Implemented it from
|
||||||
|
scratch, based on the EF9340/41 datasheet (sent by Simon Scudder), on
|
||||||
|
the technical docs made by Soeren Gust and disassembling the VP+ bios.
|
||||||
|
You will need a Videopac+ bios image file in order to use this feature.
|
||||||
|
You can use the -bios option to select it, rename the file to o2rom.bin,
|
||||||
|
or select it in O2EM Launcher settings. Please note that a few O2 games
|
||||||
|
do not work with the VP+ bios, so most likely you will need both bios
|
||||||
|
versions to be able to run all the games. For copyright reasons these
|
||||||
|
files are not included with O2EM, but you can find them in the Internet.
|
||||||
|
|
||||||
|
- Added a default configuration file. Now you can specify your preferred
|
||||||
|
options in a configuration file, instead of typing it every time you
|
||||||
|
execute the emulator. The command line options override the default
|
||||||
|
settings in the file. See O2EM.txt for more.
|
||||||
|
|
||||||
|
- Extended the -s1 and -s2 switches to allow customizable keys with the
|
||||||
|
joystick emulation. Based on a patch written by Zimmerman that
|
||||||
|
implemented customizable keys it in a different way. See O2EM.txt for
|
||||||
|
more.
|
||||||
|
|
||||||
|
- Added support to the Four in 1 Row game.
|
||||||
|
|
||||||
|
- Added the -exrom switch to enable the use of a special ROM mapping mode.
|
||||||
|
See O2EM.txt for more.
|
||||||
|
|
||||||
|
- Improved the sound with Frogger and Popeye.
|
||||||
|
|
||||||
|
- Minor fixes.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
V0.90: 08/07/2002
|
||||||
|
|
||||||
|
- Fixed the color palette, based on screen shots from a real O2 console.
|
||||||
|
|
||||||
|
- Fixed a bug in the sprite drawing priority. Now in several games the
|
||||||
|
sprites look better (Demon Attack, Turtles, Atlantis, Computer Golf,
|
||||||
|
Football, Helicopter Rescue, etc.).
|
||||||
|
|
||||||
|
- Modified the emulation of sprites and characters in the border region of
|
||||||
|
the screen. Fixed the bug of character wrapping to the other side of the
|
||||||
|
screen and other problems (Atlantis and others). Now the main characters of
|
||||||
|
P.T.Barnum's Acrobats! do not fall from the edge of screen.
|
||||||
|
|
||||||
|
- Fixed the audio pitch and implemented white noise emulation. Now
|
||||||
|
explosions sound much better!
|
||||||
|
|
||||||
|
- Fixed a background line blinking problem that used to affect lots of
|
||||||
|
games.
|
||||||
|
|
||||||
|
- Fixed the color bar at the left of the screen.
|
||||||
|
|
||||||
|
- Enhanced the support for European/Pal games. Now several games look and
|
||||||
|
play better. Shark Hunter intro works correctly. Frogger and Depth Charge
|
||||||
|
are fully playable !
|
||||||
|
|
||||||
|
- Implemented an audio filter that accurately emulates the behavior of the
|
||||||
|
low-pass filter present in the audio output of the real console. The sound
|
||||||
|
is better now. (Enable it with -filter).
|
||||||
|
|
||||||
|
- Fixed the screen size. Now you can see all the graphics in the game,
|
||||||
|
including the time in Labyrinth.
|
||||||
|
|
||||||
|
- Implemented Dot Grid emulation. Now Marksman is playable.
|
||||||
|
|
||||||
|
- Implemented a cached video emulation, to make it run faster with slow
|
||||||
|
machines / video cards.
|
||||||
|
|
||||||
|
- Implemented screen shots (use the F8 key and the -scshot option)
|
||||||
|
|
||||||
|
- Implemented the sprite shifted/smooth modes. Now the main character of
|
||||||
|
Q*bert looks hi-res.
|
||||||
|
|
||||||
|
- Several minor fixes.
|
||||||
|
|
||||||
|
|
||||||
|
The following fixes were made by Soeren Gust:
|
||||||
|
|
||||||
|
|
||||||
|
- Implemented the missing JNI instruction.
|
||||||
|
|
||||||
|
- Implemented the 1kb data ROM / 3kb program ROM addressing mode used by
|
||||||
|
Musician.
|
||||||
|
|
||||||
|
- Fixed the height of the grid lines.
|
||||||
|
|
||||||
|
- Added support for 3Kb per bank
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
V0.87: 06/21/2002
|
||||||
|
|
||||||
|
- Fixed a collision bug introduced with version 0.86.
|
||||||
|
Now Cosmic Conflict runs again. Thanks to Dan Boris for reporting
|
||||||
|
this bug.
|
||||||
|
|
||||||
|
- Implemented the option to set the O2 bios file name/dir, as
|
||||||
|
requested by my friend Heitor, to enable him to support it with his
|
||||||
|
nice O2EMLauncher frontend for O2EM 0.8x, as requested by its users.
|
||||||
|
Get O2EMLauncher here: http://www.odyssey.com.br/o2emlauncher/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.86:
|
||||||
|
|
||||||
|
- Fixed a bug in the drawing of quad characters. Now you can play
|
||||||
|
Q*Bert and Nimble Numbers Ned. Some other games will also have
|
||||||
|
improved graphics or text (Popeye, Super Cobra, etc.) .
|
||||||
|
|
||||||
|
- Fixed another bug in the collision detection. Now Demon Attack
|
||||||
|
works correctly.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.85:
|
||||||
|
|
||||||
|
- Fixed the collision detection. Now you can play Killer Bees!
|
||||||
|
|
||||||
|
- Implemented partial support to mid-screen changes to the VDC
|
||||||
|
registers without interrupts. Now several games look better, and some
|
||||||
|
that didn't work can be played, including Power Lords and Super Cobra.
|
||||||
|
|
||||||
|
- Fixed a bug in the video emulation that made some games like Turtles
|
||||||
|
and Shark Hunter appear with some strange static characters.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.80:
|
||||||
|
|
||||||
|
The following changes were already implemented by Daniel Boris in version
|
||||||
|
0.701. Implemented them again in the sources based on version v0.65:
|
||||||
|
|
||||||
|
- Fixed a bug in the CPU core related to the handling of branch
|
||||||
|
instructions near page boundaries. (Without it Sid the Spellbinder
|
||||||
|
crashed after the first level).
|
||||||
|
|
||||||
|
- CPU core now jumps to the correct address on an external interrupt.
|
||||||
|
Killer Bees runs again.
|
||||||
|
|
||||||
|
- Fixed shape of '$' character and added missing 64th character to
|
||||||
|
character set (ripped the correct character data from the v0.701
|
||||||
|
executable file).
|
||||||
|
|
||||||
|
- Fixed bug in drawing of bottom grid line.
|
||||||
|
|
||||||
|
- Added Voice support. Re implemented it from scratch, based on O2
|
||||||
|
technical specs released by Dan Boris and disassembling Smithereens
|
||||||
|
and Turtles (now it always work with Turtles).
|
||||||
|
|
||||||
|
The following changes are new to version 0.80:
|
||||||
|
|
||||||
|
- Updated the code to compile with Allegro 4.0.x and to work
|
||||||
|
without changes under Windows, Linux and DOS, with optimizations
|
||||||
|
for each.
|
||||||
|
|
||||||
|
- Implemented the option of windowed or fullscreen video modes,
|
||||||
|
with scaling, centering and optional 50% scanlines.
|
||||||
|
|
||||||
|
- Cleaned the code to make it more portable and maintainable.
|
||||||
|
|
||||||
|
- Improved timing, using the most accurate way available for
|
||||||
|
each platform.
|
||||||
|
|
||||||
|
- Fixed the keyboard scan code translation table.
|
||||||
|
|
||||||
|
- Fixed and improved the built-in debugger.
|
||||||
|
|
||||||
|
- Fixed the reset. It now works with Turtles.
|
||||||
|
|
||||||
|
- Fixed joystick detection code.
|
||||||
|
|
||||||
|
- Implemented variable speed control relative to original O2.
|
||||||
|
|
||||||
|
- Implemented individual volume control for sounds and voice.
|
||||||
|
|
||||||
|
- Implemented Pause/Information (F1).
|
||||||
|
|
||||||
|
- Avoided collision of keyboard input with key joystick
|
||||||
|
emulation. Now Caps Lock enables/disables the W,D,S,A,Space keys
|
||||||
|
for keyboard input when they are used by joystick emulation.
|
||||||
|
Works well with games like K.C.'s Krazy Chase.
|
||||||
|
|
||||||
|
- It now releases more CPU time to the system (if possible).
|
||||||
|
|
||||||
|
- Other minor changes/fixes.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
|
||||||
|
The Clarified Artistic License
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The intent of this document is to state the conditions under which a
|
||||||
|
Package may be copied, such that the Copyright Holder maintains some
|
||||||
|
semblance of artistic control over the development of the package,
|
||||||
|
while giving the users of the package the right to use and distribute
|
||||||
|
the Package in a more-or-less customary fashion, plus the right to make
|
||||||
|
reasonable modifications.
|
||||||
|
|
||||||
|
Definitions:
|
||||||
|
|
||||||
|
"Package" refers to the collection of files distributed by the
|
||||||
|
Copyright Holder, and derivatives of that collection of files
|
||||||
|
created through textual modification.
|
||||||
|
|
||||||
|
"Standard Version" refers to such a Package if it has not been
|
||||||
|
modified, or has been modified in accordance with the wishes
|
||||||
|
of the Copyright Holder as specified below.
|
||||||
|
|
||||||
|
"Copyright Holder" is whoever is named in the copyright or
|
||||||
|
copyrights for the package.
|
||||||
|
|
||||||
|
"You" is you, if you're thinking about copying or distributing
|
||||||
|
this Package.
|
||||||
|
|
||||||
|
"Distribution fee" is a fee you charge for providing a copy
|
||||||
|
of this Package to another party.
|
||||||
|
|
||||||
|
"Freely Available" means that no fee is charged for the right to
|
||||||
|
use the item, though there may be fees involved in handling the
|
||||||
|
item. It also means that recipients of the item may redistribute
|
||||||
|
it under the same conditions they received it.
|
||||||
|
|
||||||
|
1. You may make and give away verbatim copies of the source form of the
|
||||||
|
Standard Version of this Package without restriction, provided that you
|
||||||
|
duplicate all of the original copyright notices and associated disclaimers.
|
||||||
|
|
||||||
|
2. You may apply bug fixes, portability fixes and other modifications
|
||||||
|
derived from the Public Domain, or those made Freely Available, or from
|
||||||
|
the Copyright Holder. A Package modified in such a way shall still be
|
||||||
|
considered the Standard Version.
|
||||||
|
|
||||||
|
3. You may otherwise modify your copy of this Package in any way, provided
|
||||||
|
that you insert a prominent notice in each changed file stating how and
|
||||||
|
when you changed that file, and provided that you do at least ONE of the
|
||||||
|
following:
|
||||||
|
|
||||||
|
a) place your modifications in the Public Domain or otherwise make them
|
||||||
|
Freely Available, such as by posting said modifications to Usenet or an
|
||||||
|
equivalent medium, or placing the modifications on a major network
|
||||||
|
archive site allowing unrestricted access to them, or by allowing the
|
||||||
|
Copyright Holder to include your modifications in the Standard Version
|
||||||
|
of the Package.
|
||||||
|
|
||||||
|
b) use the modified Package only within your corporation or organization.
|
||||||
|
|
||||||
|
c) rename any non-standard executables so the names do not conflict
|
||||||
|
with standard executables, which must also be provided, and provide
|
||||||
|
a separate manual page for each non-standard executable that clearly
|
||||||
|
documents how it differs from the Standard Version.
|
||||||
|
|
||||||
|
d) make other distribution arrangements with the Copyright Holder.
|
||||||
|
|
||||||
|
e) permit and encourge anyone who receives a copy of the modified Package
|
||||||
|
permission to make your modifications Freely Available
|
||||||
|
in some specific way.
|
||||||
|
|
||||||
|
|
||||||
|
4. You may distribute the programs of this Package in object code or
|
||||||
|
executable form, provided that you do at least ONE of the following:
|
||||||
|
|
||||||
|
a) distribute a Standard Version of the executables and library files,
|
||||||
|
together with instructions (in the manual page or equivalent) on where
|
||||||
|
to get the Standard Version.
|
||||||
|
|
||||||
|
b) accompany the distribution with the machine-readable source of
|
||||||
|
the Package with your modifications.
|
||||||
|
|
||||||
|
c) give non-standard executables non-standard names, and clearly
|
||||||
|
document the differences in manual pages (or equivalent), together
|
||||||
|
with instructions on where to get the Standard Version.
|
||||||
|
|
||||||
|
d) make other distribution arrangements with the Copyright Holder.
|
||||||
|
|
||||||
|
e) offer the machine-readable source of the Package, with your
|
||||||
|
modifications, by mail order.
|
||||||
|
|
||||||
|
5. You may charge a distribution fee for any distribution of this Package.
|
||||||
|
If you offer support for this Package, you may charge any fee you choose
|
||||||
|
for that support. You may not charge a license fee for the right to use
|
||||||
|
this Package itself. You may distribute this Package in aggregate with
|
||||||
|
other (possibly commercial and possibly nonfree) programs as part of a
|
||||||
|
larger (possibly commercial and possibly nonfree) software distribution,
|
||||||
|
and charge license fees for other parts of that software distribution,
|
||||||
|
provided that you do not advertise this Package as a product of your own.
|
||||||
|
If the Package includes an interpreter, You may embed this Package's
|
||||||
|
interpreter within an executable of yours (by linking); this shall be
|
||||||
|
construed as a mere form of aggregation, provided that the complete
|
||||||
|
Standard Version of the interpreter is so embedded.
|
||||||
|
|
||||||
|
6. The scripts and library files supplied as input to or produced as
|
||||||
|
output from the programs of this Package do not automatically fall
|
||||||
|
under the copyright of this Package, but belong to whoever generated
|
||||||
|
them, and may be sold commercially, and may be aggregated with this
|
||||||
|
Package. If such scripts or library files are aggregated with this
|
||||||
|
Package via the so-called "undump" or "unexec" methods of producing a
|
||||||
|
binary executable image, then distribution of such an image shall
|
||||||
|
neither be construed as a distribution of this Package nor shall it
|
||||||
|
fall under the restrictions of Paragraphs 3 and 4, provided that you do
|
||||||
|
not represent such an executable image as a Standard Version of this
|
||||||
|
Package.
|
||||||
|
|
||||||
|
7. C subroutines (or comparably compiled subroutines in other
|
||||||
|
languages) supplied by you and linked into this Package in order to
|
||||||
|
emulate subroutines and variables of the language defined by this
|
||||||
|
Package shall not be considered part of this Package, but are the
|
||||||
|
equivalent of input as in Paragraph 6, provided these subroutines do
|
||||||
|
not change the language in any way that would cause it to fail the
|
||||||
|
regression tests for the language.
|
||||||
|
|
||||||
|
8. Aggregation of the Standard Version of the Package with a commercial
|
||||||
|
distribution is always permitted provided that the use of this Package
|
||||||
|
is embedded; that is, when no overt attempt is made to make this Package's
|
||||||
|
interfaces visible to the end user of the commercial distribution.
|
||||||
|
Such use shall not be construed as a distribution of this Package.
|
||||||
|
|
||||||
|
9. The name of the Copyright Holder may not be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
The End
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
CC = x86_64-nt64-midipix-gcc
|
||||||
|
|
||||||
|
CCFLAGS:= \
|
||||||
|
-Wall -Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=implicit-function-declaration \
|
||||||
|
-std=c99 -fomit-frame-pointer -fvisibility=hidden \
|
||||||
|
-D_GNU_SOURCE \
|
||||||
|
-O0 -g
|
||||||
|
|
||||||
|
TARGET = o2em.wbx
|
||||||
|
|
||||||
|
LDFLAGS = -Wl,--dynamicbase,--export-all-symbols
|
||||||
|
|
||||||
|
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||||
|
SRCS:=$(shell find $(ROOT_DIR) -type f -name '*.c')
|
||||||
|
OBJ_DIR:=$(ROOT_DIR)/obj
|
||||||
|
|
||||||
|
_OBJS:=$(SRCS:.c=.o)
|
||||||
|
OBJS:=$(patsubst $(ROOT_DIR)%,$(OBJ_DIR)%,$(_OBJS))
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
@$(CC) -c -o $@ $< $(CCFLAGS)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
.PHONY: clean all
|
||||||
|
|
||||||
|
$(TARGET).in: $(OBJS)
|
||||||
|
@$(CC) -o $@ $(LDFLAGS) $(CCFLAGS) $(OBJS) ../emulibc/libemuhost.so
|
||||||
|
|
||||||
|
$(TARGET): $(TARGET).in
|
||||||
|
# strip $< -o $@ -R /4 -R /14 -R /29 -R /41 -R /55 -R /67 -R /78 -R /89 -R /104
|
||||||
|
cp $< $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJ_DIR)
|
||||||
|
rm -f $(TARGET).in
|
||||||
|
rm -f $(TARGET)
|
||||||
|
|
||||||
|
#install:
|
||||||
|
# $(CP) $(TARGET) $(DEST_$(ARCH))
|
|
@ -0,0 +1,341 @@
|
||||||
|
|
||||||
|
|
||||||
|
O2EM v1.18 (Jan/2007)
|
||||||
|
|
||||||
|
an Odyssey 2 & Videopac+ emulator
|
||||||
|
|
||||||
|
copyright 1996/1998 by Daniel Boris <dboris@comcast.net>
|
||||||
|
|
||||||
|
Developed by Daniel Boris, Andre de la Rocha and Arlindo Oliveira
|
||||||
|
|
||||||
|
This package is released under the
|
||||||
|
Clarified Artistic License (see COPYING)
|
||||||
|
|
||||||
|
Project Homepage
|
||||||
|
http://o2em.sourceforge.net
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
O2EM is an open source Odyssey2 / Videopac console emulator, created by
|
||||||
|
Daniel Boris in 1996. Since version 0.80 it has been developed by André de
|
||||||
|
la Rocha and since version 1.16 it has been developed by Arlindo M. de Oliveira.
|
||||||
|
|
||||||
|
This release includes the source code for O2EM v1.18 and binaries for
|
||||||
|
Windows. The sources probably can also be compiled under other platforms
|
||||||
|
that support the Allegro game library. The binary version for Linux/X11 and
|
||||||
|
DOS continues available just until the version 1.16.
|
||||||
|
|
||||||
|
With the Windows binary, the latest stable version of the Allegro DLL is also
|
||||||
|
included. To use the Linux version you must get the Allegro library for Linux
|
||||||
|
yourself and install it as root. The DOS version does not need additional
|
||||||
|
files.
|
||||||
|
|
||||||
|
O2EM is a command line based program, but there are several Windows frontends
|
||||||
|
you can use. The "official" one is O2EM Launcher, created by Heitor
|
||||||
|
Barcellos.
|
||||||
|
|
||||||
|
In order to build O2EM from its sources, you need either the MingW or Cygwin
|
||||||
|
packages on Windows, DJGPP on DOS and GCC on Linux. See the links below.
|
||||||
|
|
||||||
|
The latest version of O2EM can be found at http://o2em.sourceforge.net If you
|
||||||
|
want to send bug reports, or be part of the O2EM development, go to the O2EM
|
||||||
|
project page at SourceForge : http://sourceforge.net/projects/o2em/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Useful links:
|
||||||
|
|
||||||
|
Dan Boris' home page: http://www.atarihq.com/danb/
|
||||||
|
Allegro library: http://alleg.sourceforge.net/
|
||||||
|
MingW C/C++ compiler: http://sourceforge.net/projects/mingw/
|
||||||
|
Soeren Gust page : http://soeren.informationstheater.de/
|
||||||
|
Odyssey2 Home: http://www.classicgaming.com/o2home/
|
||||||
|
Odysseymania the brazilian webpage : http://odysseymania.classicgaming.com.br
|
||||||
|
OdysseyBR Group: http://gamesource.groups.yahoo.com/group/OdysseyBR/
|
||||||
|
Videopac Forum: http://www.videopac.org
|
||||||
|
|
||||||
|
Acknowledgments:
|
||||||
|
|
||||||
|
|
||||||
|
We wish to thank the following people:
|
||||||
|
|
||||||
|
Keita Iida (Keita/Pooka/Fygar)
|
||||||
|
for his enthusiasm, for the O2EM beta testing, and general encouragement.
|
||||||
|
|
||||||
|
Marco Kerstens (MarcoK)
|
||||||
|
for providing Videopac schematics, and general support.
|
||||||
|
|
||||||
|
Matthew Pritchard
|
||||||
|
for sending some official O2 programming documents.
|
||||||
|
|
||||||
|
Bo Krogsgaard (Therion23)
|
||||||
|
for putting the idea of doing the emulator into my head to start with.
|
||||||
|
|
||||||
|
Jason F. Gohlke
|
||||||
|
for providing valuable Voice tech info as well as the voice samples.
|
||||||
|
|
||||||
|
Soeren Gust : For sending his patches to O2EM and for technical
|
||||||
|
information about the console. Part of his technical document was
|
||||||
|
used to implement VP+ emulation.
|
||||||
|
|
||||||
|
René van den Enden : for providing information about several
|
||||||
|
unsupported games and other help.
|
||||||
|
|
||||||
|
Simon Scudder : for sending technical information about the O2
|
||||||
|
(including the datasheet of the VP+ gfx chipset), sampled sounds and
|
||||||
|
his nice O2 disassembler.
|
||||||
|
|
||||||
|
Heitor Barcellos : for creating the O2EM Launcher frontend.
|
||||||
|
|
||||||
|
Marcelo Ribeiro : for the icon used with the windows version of O2EM,
|
||||||
|
bug reports, and for information about O2 games.
|
||||||
|
|
||||||
|
Rafael : for compiling a big list of bugs present in O2EM v0.87.
|
||||||
|
|
||||||
|
Zimmerman : for sending his patch to add key customization, on which
|
||||||
|
v1.00 customization was based.
|
||||||
|
|
||||||
|
Arlindo de Oliveira : for sending patches to fix bugs in O2EM and for
|
||||||
|
his interest in keeping the O2 emulation alive.
|
||||||
|
|
||||||
|
The members of the OdysseyBR user group: for several bug reports, as
|
||||||
|
well for support in general.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Building:
|
||||||
|
|
||||||
|
o2em depends on Allegro, for Ubuntu / Debian, run:
|
||||||
|
|
||||||
|
sudo apt-get install liballegro4-dev
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Quick Setup:
|
||||||
|
|
||||||
|
To get O2EM up and running quickly follow these steps:
|
||||||
|
|
||||||
|
1. Unzip the O2EM archive on your hard drive, that will create the necessary
|
||||||
|
standard directories: ROMS, BIOS and VOICE into the main directory O2EM118.
|
||||||
|
2. Download the bios ROM O2ROM.BIN (or G7400.BIN, or C52.BIN, or JOPAC.BIN)
|
||||||
|
and put it into BIOS directory.
|
||||||
|
3. Download one or more game ROMs, for example KCMUNCH.BIN for KC Munchkin and
|
||||||
|
put the ROM in ROMS directory.
|
||||||
|
4. From the O2EM118 directory type: o2em KCMUNCH.BIN to start the game.If wants
|
||||||
|
to play KC Munchkin with BIOS VP+, type: o2em KCMUNCH.BIN -g7400
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Setup:
|
||||||
|
|
||||||
|
Before you can run O2EM you need a copy of the Odyssey2 or Videopac bios
|
||||||
|
ROM. For copyright reasons, this ROM image can not be included in this
|
||||||
|
archive. This ROM image is stored inside the 8048 processor and can be read
|
||||||
|
out with the appropriate equipment. The image should be 1024 bytes long and
|
||||||
|
should be in the BIOS directory into the main directory O2EM118.
|
||||||
|
|
||||||
|
You will also need cartridge images, but again for copyright reasons
|
||||||
|
these can not be provided. PLEASE DO NOT E-mail us asking for ROM images! All
|
||||||
|
messages asking for ROM images will be promptly deleted.
|
||||||
|
|
||||||
|
If you wish to use Voice emulation for games like KC's Krazy Chase.
|
||||||
|
Download the voice samples and unzip them into the VOICE directory
|
||||||
|
into the main directory O2EM118. There are two sets of voice samples,
|
||||||
|
mainsamp.zip which is the main voice samples and sidsamp.zip which are the
|
||||||
|
samples used by the game Sid the Spellbinder. You only need the Sid samples
|
||||||
|
if you want voice in that game.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
|
||||||
|
o2em <file> [options]
|
||||||
|
|
||||||
|
<file> = file to load with extension
|
||||||
|
|
||||||
|
|
||||||
|
options:
|
||||||
|
|
||||||
|
-help Help display
|
||||||
|
|
||||||
|
-wsize=n Window size used by the emulator (1=original, 2=double size, etc.)
|
||||||
|
|
||||||
|
-fullscreen Use full screen mode
|
||||||
|
|
||||||
|
-scanlines Enable scanlines use by the video emulation. Scanlines are a
|
||||||
|
feature that makes your display look like a TV screen.
|
||||||
|
|
||||||
|
-nosound Turn off sound emulation
|
||||||
|
|
||||||
|
-novoice Turn off voice emulation
|
||||||
|
|
||||||
|
-svolume=n Set sound volume (0-100)
|
||||||
|
|
||||||
|
-vvolume=n Set voice volume (0-100)
|
||||||
|
|
||||||
|
-debug Start the emulator in debug mode
|
||||||
|
|
||||||
|
-speed=n Relative speed (100 = original speed)
|
||||||
|
|
||||||
|
-nolimit Turn off speed limiter
|
||||||
|
|
||||||
|
-bios=file Set the file name and directory to find the console
|
||||||
|
bios. By default it looks for a file named o2rom.bin.
|
||||||
|
You can use a bios file from an Odyssey2, Videopac or
|
||||||
|
Videopac+ console. If you want to run VP+ games (in
|
||||||
|
VP+ mode) then you need a VP+ bios.
|
||||||
|
|
||||||
|
-romdir=path Set the directory to find the game rom. By default it
|
||||||
|
looks for path named .../roms
|
||||||
|
|
||||||
|
-biosdir=path Set the directory to find the console bios. By default it
|
||||||
|
looks for path named .../bios
|
||||||
|
|
||||||
|
-o2rom Start the emulator with Odyssey 2 bios (default for most games).
|
||||||
|
|
||||||
|
-c52 Start the emulator with french Odyssey 2 bios.
|
||||||
|
|
||||||
|
-g7400 Start the emulator with VP+ bios (default for detected VP+ only games).
|
||||||
|
|
||||||
|
-jopac Start the emulator with french VP+ bios.
|
||||||
|
|
||||||
|
-euro This option enables the use of European timing / 50Hz mode.
|
||||||
|
This option is usually not needed as most of the games that
|
||||||
|
really require this mode will be auto-detected.
|
||||||
|
|
||||||
|
-filter Enable the low-pass audio filter.
|
||||||
|
|
||||||
|
-scshot=file Set the screen shot file name or template. The screen shot
|
||||||
|
will be saved when you press the F8 key in the emulator.
|
||||||
|
The extension of the file you give will set the file type.
|
||||||
|
supported file types are bmp, pcx and tga. You can also give
|
||||||
|
a template to save several files, using the @ character.
|
||||||
|
Using an option like -scshot=dump@.bmp will save files with
|
||||||
|
names like dump00.bmp, dump01.bmp, etc. The pictures will
|
||||||
|
have a resolution of (320x240)*wsize.
|
||||||
|
|
||||||
|
-exrom Enable the use of an alternative ROM mapping for 4Kb games, to
|
||||||
|
support some games that use a special 3kb program rom/1kb data
|
||||||
|
ROM mode. The only known that use it are Four in 1 Row and
|
||||||
|
Musician and both are detected by their CRC and set correctly.
|
||||||
|
So this option is to be used only with games that are currently
|
||||||
|
unknown to O2EM. Do not enable it as default, as it will make
|
||||||
|
all the 4kb games that do not use this special mode crash.
|
||||||
|
|
||||||
|
-s0=QUIT,PAUSE,DEBUG,RESET,SCREENCAP,SAVE,LOAD,INJECT_HIGH
|
||||||
|
These option defines which keys are used for some of the system
|
||||||
|
keys, if you use this option, you have to enter all 8 keys, to
|
||||||
|
override the original keys (ESC,F1,F4,F5,F8,F2,F3,F6)
|
||||||
|
|
||||||
|
-s1=mode/keys Define stick 1 mode/keys
|
||||||
|
-s2=mode/keys Define stick 2 mode/keys
|
||||||
|
|
||||||
|
These options define how the console joysticks are emulated.
|
||||||
|
You can use a joystick connected to your computer or use
|
||||||
|
the keyboard. You can specify a mode number (compatible with
|
||||||
|
previous versions of O2EM) to disable the joystick emulation,
|
||||||
|
to select an actual joystick or to set a default keyboard
|
||||||
|
emulation mode :
|
||||||
|
0=Disable,
|
||||||
|
1=Default Right keys (arrows keys and right shift)
|
||||||
|
2=Default Left keys (W,S,A,D,SPACE)
|
||||||
|
3=Joystick
|
||||||
|
Example: -s1=1 -s2=3
|
||||||
|
|
||||||
|
You can also specify a list of 5 keyboard codes that will
|
||||||
|
be used to emulate the joystick, separated by comas
|
||||||
|
(without spaces), using this order : UP,DOWN,LEFT,RIGHT,FIRE.
|
||||||
|
The following codes are accepted (not case sensitive):
|
||||||
|
A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0_PAD,1_PAD,2_PAD,3_PAD,4_PAD,5_PAD,6_PAD,7_PAD,8_PAD,9_PAD,
|
||||||
|
TILDE, MINUS, EQUALS, BACKSPACE, TAB, OPENBRACE, CLOSEBRACE,
|
||||||
|
ENTER, COLON, QUOTE, BACKSLASH, BACKSLASH2, COMMA, STOP,
|
||||||
|
SLASH, SPACE, INSERT, DEL, HOME, END, PGUP, PGDN, LEFT,
|
||||||
|
RIGHT, UP, DOWN, SLASH_PAD, ASTERISK, MINUS_PAD, PLUS_PAD,
|
||||||
|
DEL_PAD, ENTER_PAD, PRTSCR, PAUSE, ABNT_C1, YEN, KANA, AT,
|
||||||
|
CIRCUMFLEX, COLON2, KANJI, LSHIFT, RSHIFT, LCONTROL,
|
||||||
|
RCONTROL, ALT, ALTGR, LWIN, RWIN, MENU, SCRLOCK, NUMLOCK
|
||||||
|
Example: -s1=y,h,g,j,lcontrol -s2=8_PAD,5_PAD,4_PAD,6_PAD,RCONTROL
|
||||||
|
|
||||||
|
-scoreadr=address where the high-score is saved for specific rom
|
||||||
|
-scoretype=type how the high-score is saved for specific rom
|
||||||
|
-score=highscore default highscore on launch ("inject" with F6)
|
||||||
|
-scorefile=file file where the highscore is saved on exit
|
||||||
|
|
||||||
|
-savefile=file filename for save/load state
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Default configuration file:
|
||||||
|
|
||||||
|
O2EM now can use a configuration file to set the default options, so you can
|
||||||
|
specify your preferred options in this file, instead of typing it every time
|
||||||
|
you execute the emulator. The command line options override the default
|
||||||
|
settings in the file. This file must be called o2em_def.cfg and be in the
|
||||||
|
same directory of O2EM118. This configuration file is a text file where you can
|
||||||
|
put the same options you would use when calling O2EM by the command line, but
|
||||||
|
each option must be in a different line and you should not precede it with
|
||||||
|
the - character. You can also put comment lines in the file, starting the
|
||||||
|
line with the # character. Example configuration file:
|
||||||
|
|
||||||
|
# My config
|
||||||
|
wsize=3
|
||||||
|
Euro
|
||||||
|
scanlines
|
||||||
|
filter
|
||||||
|
g7400
|
||||||
|
s1=8_pad,5_pad,4_pad,6_pad,rcontrol
|
||||||
|
|
||||||
|
|
||||||
|
You disable any option set in this file when you call O2EM in the command
|
||||||
|
line, passing the =0 parameter to the option. For this example configuration,
|
||||||
|
you could disable the filter option set in the file putting -filter=0 when
|
||||||
|
you call O2EM.
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Controls:
|
||||||
|
|
||||||
|
Arrow keys + L = Default joystick 1 emulation
|
||||||
|
|
||||||
|
W,D,S,A + Space = Default joystick 2 emulation
|
||||||
|
|
||||||
|
ESC/F12 = Leave the emulator
|
||||||
|
|
||||||
|
F1 = Pause/Information
|
||||||
|
|
||||||
|
F2 = Save State-File
|
||||||
|
|
||||||
|
F3 = Load State-File
|
||||||
|
|
||||||
|
F4 = Enter debugger
|
||||||
|
|
||||||
|
F5 = Reset emulator (same as pressing the reset on the O2 keyboard)
|
||||||
|
|
||||||
|
F6 = Inject Highscore
|
||||||
|
|
||||||
|
F8 = Make a screen shot
|
||||||
|
|
||||||
|
Caps Lock = Enables/Disables the O2 keyboard input of the keys used by
|
||||||
|
joystick emulation
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Debugger:
|
||||||
|
|
||||||
|
The emulator comes with a built in debugger that was used for development.
|
||||||
|
The debugger is not very polished and fairly incomplete but it can be useful
|
||||||
|
for single stepping through programs and watching their behavior.
|
||||||
|
|
||||||
|
H = display help
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* O2 audio emulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "vmachine.h"
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
|
#define SAMPLE_RATE 44100
|
||||||
|
#define PERIOD1 11
|
||||||
|
#define PERIOD2 44
|
||||||
|
|
||||||
|
#define SOUND_BUFFER_LEN 1056
|
||||||
|
|
||||||
|
#define AUD_CTRL 0xAA
|
||||||
|
#define AUD_D0 0xA7
|
||||||
|
#define AUD_D1 0xA8
|
||||||
|
#define AUD_D2 0xA9
|
||||||
|
|
||||||
|
int sound_IRQ;
|
||||||
|
|
||||||
|
static double flt_a = 0.0, flt_b = 0.0;
|
||||||
|
static unsigned char flt_prv = 0;
|
||||||
|
|
||||||
|
void audio_process(unsigned char *buffer)
|
||||||
|
{
|
||||||
|
unsigned long aud_data;
|
||||||
|
int volume, re_circ, noise, enabled, intena, period, pnt, cnt, rndbit, pos;
|
||||||
|
|
||||||
|
aud_data = (VDCwrite[AUD_D2] | (VDCwrite[AUD_D1] << 8) | (VDCwrite[AUD_D0] << 16));
|
||||||
|
|
||||||
|
intena = VDCwrite[0xA0] & 0x04;
|
||||||
|
|
||||||
|
pnt = cnt = 0;
|
||||||
|
|
||||||
|
noise = VDCwrite[AUD_CTRL] & 0x10;
|
||||||
|
enabled = VDCwrite[AUD_CTRL] & 0x80;
|
||||||
|
rndbit = (enabled && noise) ? (rand() % 2) : 0;
|
||||||
|
|
||||||
|
while (pnt < SOUND_BUFFER_LEN)
|
||||||
|
{
|
||||||
|
pos = (tweakedaudio) ? (pnt / 3) : (MAXLINES - 1);
|
||||||
|
volume = AudioVector[pos] & 0x0F;
|
||||||
|
enabled = AudioVector[pos] & 0x80;
|
||||||
|
period = (AudioVector[pos] & 0x20) ? PERIOD1 : PERIOD2;
|
||||||
|
re_circ = AudioVector[pos] & 0x40;
|
||||||
|
|
||||||
|
buffer[pnt++] = (enabled) ? ((aud_data & 0x01) ^ rndbit) * (0x10 * volume) : 0;
|
||||||
|
cnt++;
|
||||||
|
|
||||||
|
if (cnt >= period)
|
||||||
|
{
|
||||||
|
cnt = 0;
|
||||||
|
aud_data = (re_circ) ? ((aud_data >> 1) | ((aud_data & 1) << 23)) : (aud_data >> 1);
|
||||||
|
rndbit = (enabled && noise) ? (rand() % 2) : 0;
|
||||||
|
|
||||||
|
if (enabled && intena && (!sound_IRQ))
|
||||||
|
{
|
||||||
|
sound_IRQ = 1;
|
||||||
|
ext_IRQ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (app_data.filter)
|
||||||
|
//filter(buffer, SOUND_BUFFER_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_audio(void)
|
||||||
|
{
|
||||||
|
unsigned char scratch[4096];
|
||||||
|
audio_process(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_audio(void)
|
||||||
|
{
|
||||||
|
sound_IRQ = 0;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __AUDIO_H
|
||||||
|
#define __AUDIO_H
|
||||||
|
|
||||||
|
void update_audio(void);
|
||||||
|
void init_audio(void);
|
||||||
|
void init_sound_stream(void);
|
||||||
|
|
||||||
|
|
||||||
|
extern int sound_IRQ;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "bitmap.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void clear(Bitmap* b)
|
||||||
|
{
|
||||||
|
memset(b->dat, 0, b->w * b->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap* NewBitmap(int w, int h)
|
||||||
|
{
|
||||||
|
Bitmap* b = malloc(sizeof(Bitmap) + w * h);
|
||||||
|
b->w = w;
|
||||||
|
b->h = h;
|
||||||
|
b->line = malloc(sizeof(uint8_t*) * h);
|
||||||
|
b->dat = malloc(w * h);
|
||||||
|
for (int i = 0; i < h; i++)
|
||||||
|
b->line[i] = b->dat + w * i;
|
||||||
|
|
||||||
|
clear(b);
|
||||||
|
return b;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t** line;
|
||||||
|
uint8_t* dat;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
} Bitmap;
|
||||||
|
|
||||||
|
void clear(Bitmap* b);
|
||||||
|
Bitmap* NewBitmap(int w, int h);
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __CONFIG_H
|
||||||
|
#define __CONFIG_H
|
||||||
|
|
||||||
|
#define O2EM_VERSION "1.18"
|
||||||
|
#define RELEASE_DATE "(Jan/2007)"
|
||||||
|
|
||||||
|
#define ROM_O2 1
|
||||||
|
#define ROM_G7400 2
|
||||||
|
#define ROM_C52 3
|
||||||
|
#define ROM_JOPAC 4
|
||||||
|
#define ROM_UNKNOWN 99
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,63 @@
|
||||||
|
#ifndef CPU_H
|
||||||
|
#define CPU_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
extern Byte acc; /* Accumulator */
|
||||||
|
extern ADDRESS pc; /* Program counter */
|
||||||
|
|
||||||
|
extern Byte itimer; /* Internal timer */
|
||||||
|
extern Byte reg_pnt; /* pointer to register bank */
|
||||||
|
extern Byte timer_on; /* 0=timer off/1=timer on */
|
||||||
|
extern Byte count_on; /* 0=count off/1=count on */
|
||||||
|
|
||||||
|
extern Byte t_flag; /* Timer flag */
|
||||||
|
|
||||||
|
extern Byte psw; /* Processor status word */
|
||||||
|
extern Byte sp; /* Stack pointer (part of psw) */
|
||||||
|
|
||||||
|
extern Byte p1; /* I/O port 1 */
|
||||||
|
extern Byte p2; /* I/O port 2 */
|
||||||
|
|
||||||
|
extern Byte xirq_pend;
|
||||||
|
extern Byte tirq_pend;
|
||||||
|
|
||||||
|
void init_cpu(void);
|
||||||
|
int64_t cpu_exec(int64_t ncycles);
|
||||||
|
void ext_IRQ(void);
|
||||||
|
void tim_IRQ(void);
|
||||||
|
void make_psw_debug(void);
|
||||||
|
|
||||||
|
Byte acc; /* Accumulator */
|
||||||
|
ADDRESS pc; /* Program counter */
|
||||||
|
|
||||||
|
Byte itimer; /* Internal timer */
|
||||||
|
Byte reg_pnt; /* pointer to register bank */
|
||||||
|
Byte timer_on; /* 0=timer off/1=timer on */
|
||||||
|
Byte count_on; /* 0=count off/1=count on */
|
||||||
|
Byte psw; /* Processor status word */
|
||||||
|
Byte sp; /* Stack pointer (part of psw) */
|
||||||
|
|
||||||
|
Byte p1; /* I/O port 1 */
|
||||||
|
Byte p2; /* I/O port 2 */
|
||||||
|
Byte xirq_pend; /* external IRQ pending */
|
||||||
|
Byte tirq_pend; /* timer IRQ pending */
|
||||||
|
Byte t_flag; /* Timer flag */
|
||||||
|
|
||||||
|
ADDRESS lastpc;
|
||||||
|
ADDRESS A11; /* PC bit 11 */
|
||||||
|
ADDRESS A11ff;
|
||||||
|
Byte bs; /* Register Bank (part of psw) */
|
||||||
|
Byte f0; /* Flag Bit (part of psw) */
|
||||||
|
Byte f1; /* Flag Bit 1 */
|
||||||
|
Byte ac; /* Aux Carry (part of psw) */
|
||||||
|
Byte cy; /* Carry flag (part of psw) */
|
||||||
|
Byte xirq_en; /* external IRQ's enabled */
|
||||||
|
Byte tirq_en; /* Timer IRQ enabled */
|
||||||
|
Byte irq_ex; /* IRQ executing */
|
||||||
|
|
||||||
|
int master_count;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* CPU_H */
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* CRC32 functions used to identify files
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Some stuff ported from here:
|
||||||
|
// http://www.opensource.apple.com/source/xnu/xnu-1504.7.4/bsd/libkern/crc32.c
|
||||||
|
|
||||||
|
#include "crc32.h"
|
||||||
|
|
||||||
|
static const uint32_t crc32tab[256] = {
|
||||||
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||||
|
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||||
|
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||||
|
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||||
|
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||||
|
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||||
|
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||||
|
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||||
|
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||||
|
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||||
|
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||||
|
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||||
|
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||||
|
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||||
|
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||||
|
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||||
|
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||||
|
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||||
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||||
|
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||||
|
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||||
|
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||||
|
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||||
|
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||||
|
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||||
|
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||||
|
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||||
|
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||||
|
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||||
|
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||||
|
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||||
|
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||||
|
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||||
|
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||||
|
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||||
|
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||||
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||||
|
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||||
|
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||||
|
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||||
|
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||||
|
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||||
|
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||||
|
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||||
|
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||||
|
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||||
|
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||||
|
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||||
|
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||||
|
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||||
|
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||||
|
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||||
|
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||||
|
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||||
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||||
|
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||||
|
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||||
|
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||||
|
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||||
|
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||||
|
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||||
|
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||||
|
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||||
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t crc32_buf(const void *buf, size_t size)
|
||||||
|
{
|
||||||
|
uint32_t crc = ~0;
|
||||||
|
const uint8_t *p = buf;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
crc = (crc >> 8) ^ crc32tab[(crc ^ (*p++)) & 0xFF];
|
||||||
|
return ~crc;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "types.h"
|
||||||
|
uint32_t crc32_buf(const void *buf, size_t len);
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* O2 character table
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "cset.h"
|
||||||
|
|
||||||
|
const Byte cset[512] = {
|
||||||
|
0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
|
||||||
|
0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
|
||||||
|
0x3C, 0x66, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00,
|
||||||
|
0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00,
|
||||||
|
0xCC, 0xCC, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 0x00,
|
||||||
|
0xFE, 0xC0, 0xC0, 0x7C, 0x06, 0xC6, 0x7C, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC0, 0xFC, 0xC6, 0xC6, 0x7C, 0x00,
|
||||||
|
0xFE, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0x7C, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC6, 0x7E, 0x06, 0xC6, 0x7C, 0x00,
|
||||||
|
0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00,
|
||||||
|
0x18, 0x7E, 0x58, 0x7E, 0x1A, 0x7E, 0x18, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
|
||||||
|
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0x00,
|
||||||
|
0xFC, 0xC6, 0xC6, 0xFC, 0xC0, 0xC0, 0xC0, 0x00,
|
||||||
|
0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00,
|
||||||
|
0xFE, 0xC0, 0xC0, 0xF8, 0xC0, 0xC0, 0xFE, 0x00,
|
||||||
|
0xFC, 0xC6, 0xC6, 0xFC, 0xD8, 0xCC, 0xC6, 0x00,
|
||||||
|
0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
|
||||||
|
0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC6, 0xC6, 0xDE, 0xCC, 0x76, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC0, 0x7C, 0x06, 0xC6, 0x7C, 0x00,
|
||||||
|
0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFC, 0x00,
|
||||||
|
0xFE, 0xC0, 0xC0, 0xF8, 0xC0, 0xC0, 0xC0, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC0, 0xC0, 0xCE, 0xC6, 0x7E, 0x00,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00,
|
||||||
|
0x06, 0x06, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00,
|
||||||
|
0xC6, 0xCC, 0xD8, 0xF0, 0xD8, 0xCC, 0xC6, 0x00,
|
||||||
|
0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
|
||||||
|
0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00,
|
||||||
|
0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
|
||||||
|
0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00,
|
||||||
|
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
|
||||||
|
0xFC, 0xC6, 0xC6, 0xFC, 0xC6, 0xC6, 0xFC, 0x00,
|
||||||
|
0xC6, 0xEE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7C, 0x00, 0x7C, 0x00, 0x00, 0x00,
|
||||||
|
0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
|
||||||
|
0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0x00,
|
||||||
|
0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x00,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||||
|
0xCE, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00,
|
||||||
|
0x00, 0x00, 0x3C, 0x7E, 0x7E, 0x7E, 0x3C, 0x00,
|
||||||
|
0x1C, 0x1C, 0x18, 0x1E, 0x18, 0x18, 0x1C, 0x00,
|
||||||
|
0x1C, 0x1C, 0x18, 0x1E, 0x18, 0x34, 0x26, 0x00,
|
||||||
|
0x38, 0x38, 0x18, 0x78, 0x18, 0x2C, 0x64, 0x00,
|
||||||
|
0x38, 0x38, 0x18, 0x78, 0x18, 0x18, 0x38, 0x00,
|
||||||
|
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
|
||||||
|
0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x18, 0x18, 0x00,
|
||||||
|
0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0x00,
|
||||||
|
0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF, 0x00,
|
||||||
|
0x38, 0x38, 0x12, 0xFE, 0xB8, 0x28, 0x6C, 0x00,
|
||||||
|
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x00,
|
||||||
|
0x00, 0x00, 0x0C, 0x08, 0x08, 0xFF, 0x7E, 0x00,
|
||||||
|
0x00, 0x03, 0x63, 0xFF, 0xFF, 0x18, 0x08, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x10, 0x38, 0xFF, 0x7E, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x06, 0x6E, 0xFF, 0x7E, 0x00};
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef __CSET_H
|
||||||
|
#define __CSET_H
|
||||||
|
|
||||||
|
extern const Byte cset[512];
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Keyboard emulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "types.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "vmachine.h"
|
||||||
|
#include "vdc.h"
|
||||||
|
#include "audio.h"
|
||||||
|
#include "voice.h"
|
||||||
|
#include "vpp.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
|
void do_reset(void)
|
||||||
|
{
|
||||||
|
init_cpu();
|
||||||
|
init_roms();
|
||||||
|
init_vpp();
|
||||||
|
clearscr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_highscore(void)
|
||||||
|
{
|
||||||
|
set_score(app_data.scoretype, app_data.scoreaddress, app_data.default_highscore);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef __KEYBOARD_H
|
||||||
|
#define __KEYBOARD_H
|
||||||
|
|
||||||
|
void handle_key(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,312 @@
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "crc32.h"
|
||||||
|
#include "audio.h"
|
||||||
|
#include "vmachine.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "vdc.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "voice.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
|
#include "../emulibc/emulibc.h"
|
||||||
|
#include "../emulibc/waterboxcore.h"
|
||||||
|
|
||||||
|
char name_f, rom_f, c_j;
|
||||||
|
char pathx, *k, identify;
|
||||||
|
static int load_bios(const char *data, int size);
|
||||||
|
static int load_cart(const char *data, int size);
|
||||||
|
int parse_option(char *attr, char *val);
|
||||||
|
|
||||||
|
ECL_EXPORT int Init(const char *rom, int romlen, const char *bios, int bioslen)
|
||||||
|
{
|
||||||
|
int i, cnt, cnt2;
|
||||||
|
|
||||||
|
app_data.bank = 0;
|
||||||
|
app_data.voice = 1;
|
||||||
|
app_data.exrom = 0;
|
||||||
|
app_data.three_k = 0;
|
||||||
|
app_data.crc = 0;
|
||||||
|
app_data.euro = 0;
|
||||||
|
app_data.openb = 0;
|
||||||
|
app_data.vpp = 0;
|
||||||
|
app_data.bios = 0;
|
||||||
|
app_data.scoretype = 0;
|
||||||
|
app_data.scoreaddress = 0;
|
||||||
|
app_data.default_highscore = 0;
|
||||||
|
app_data.megaxrom = 0;
|
||||||
|
|
||||||
|
init_audio();
|
||||||
|
|
||||||
|
if (!load_bios(bios, bioslen))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!load_cart(rom, romlen))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
//if (app_data.voice)
|
||||||
|
//load_voice_samples(NULL);
|
||||||
|
init_display();
|
||||||
|
init_cpu();
|
||||||
|
init_system();
|
||||||
|
//set_score(app_data.scoretype, app_data.scoreaddress, app_data.default_highscore);
|
||||||
|
|
||||||
|
//run();
|
||||||
|
//if (app_data.scoretype != 0)
|
||||||
|
//save_highscore(get_score(app_data.scoretype, app_data.scoreaddress),
|
||||||
|
//scorefile);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ECL_EXPORT void FrameAdvance(FrameInfo* f)
|
||||||
|
{
|
||||||
|
cpu_exec(20000);
|
||||||
|
f->Samples = 735;
|
||||||
|
f->Width = 320;
|
||||||
|
f->Height = 240;
|
||||||
|
blit(f->VideoBuffer);
|
||||||
|
}
|
||||||
|
ECL_EXPORT void GetMemoryAreas(MemoryArea* m)
|
||||||
|
{
|
||||||
|
m[0].Data = intRAM;
|
||||||
|
m[0].Name = "RAM";
|
||||||
|
m[0].Size = 64;
|
||||||
|
m[0].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WORDSIZE1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ECL_EXPORT void SetInputCallback(void (*callback)(void))
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_option(char *attr, char *val)
|
||||||
|
{
|
||||||
|
int control_scheme;
|
||||||
|
if (!strcmp(attr, "nolimit"))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "novoice"))
|
||||||
|
{
|
||||||
|
app_data.voice = !(val[0] != '0');
|
||||||
|
}
|
||||||
|
else if ((!strcmp(attr, "s1")) || (!strcmp(attr, "s2")))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "fullscreen"))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "euro"))
|
||||||
|
{
|
||||||
|
app_data.euro = (val[0] != '0');
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "exrom"))
|
||||||
|
{
|
||||||
|
app_data.exrom = (val[0] != '0');
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "3k"))
|
||||||
|
{
|
||||||
|
app_data.three_k = (val[0] != '0');
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "g7400"))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "scoreadr"))
|
||||||
|
{
|
||||||
|
control_scheme = -1;
|
||||||
|
sscanf(val, "%d", &control_scheme);
|
||||||
|
if ((control_scheme >= 0) && (control_scheme <= 255))
|
||||||
|
app_data.scoreaddress = control_scheme;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid value for option %s\n", attr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "scoretype"))
|
||||||
|
{
|
||||||
|
control_scheme = -1;
|
||||||
|
sscanf(val, "%d", &control_scheme);
|
||||||
|
if ((control_scheme >= 0) && (control_scheme <= 9999))
|
||||||
|
app_data.scoretype = control_scheme;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid value for option %s\n", attr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp(attr, "score"))
|
||||||
|
{
|
||||||
|
control_scheme = -1;
|
||||||
|
sscanf(val, "%d", &control_scheme);
|
||||||
|
if ((control_scheme >= 0) && (control_scheme <= 999999))
|
||||||
|
app_data.default_highscore = control_scheme;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid value for option %s\n", attr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load_bios(const char *data, int size)
|
||||||
|
{
|
||||||
|
if (size != 1024)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
memcpy(rom_table[i], data, 1024);
|
||||||
|
}
|
||||||
|
uint32_t crc = crc32_buf(rom_table[0], 1024);
|
||||||
|
if (crc == 0x8016A315)
|
||||||
|
{
|
||||||
|
printf("Odyssey2 bios ROM loaded\n");
|
||||||
|
app_data.vpp = 0;
|
||||||
|
app_data.bios = ROM_O2;
|
||||||
|
}
|
||||||
|
else if (crc == 0xE20A9F41)
|
||||||
|
{
|
||||||
|
printf("Videopac+ G7400 bios ROM loaded\n");
|
||||||
|
app_data.vpp = 1;
|
||||||
|
app_data.bios = ROM_G7400;
|
||||||
|
}
|
||||||
|
else if (crc == 0xA318E8D6)
|
||||||
|
{
|
||||||
|
printf("C52 bios ROM loaded\n");
|
||||||
|
app_data.vpp = 0;
|
||||||
|
app_data.bios = ROM_C52;
|
||||||
|
}
|
||||||
|
else if (crc == 0x11647CA5)
|
||||||
|
{
|
||||||
|
printf("Jopac bios ROM loaded\n");
|
||||||
|
app_data.vpp = 1;
|
||||||
|
app_data.bios = ROM_JOPAC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Bios ROM loaded (unknown version)\n");
|
||||||
|
app_data.vpp = 0;
|
||||||
|
app_data.bios = ROM_UNKNOWN;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load_cart(const char *data, int size)
|
||||||
|
{
|
||||||
|
app_data.crc = crc32_buf(data, size);
|
||||||
|
if (app_data.crc == 0xAFB23F89)
|
||||||
|
app_data.exrom = 1; /* Musician */
|
||||||
|
if (app_data.crc == 0x3BFEF56B)
|
||||||
|
app_data.exrom = 1; /* Four in 1 Row! */
|
||||||
|
if (app_data.crc == 0x9B5E9356)
|
||||||
|
app_data.exrom = 1; /* Four in 1 Row! (french) */
|
||||||
|
|
||||||
|
if (app_data.crc == 0x975AB8DA || app_data.crc == 0xE246A812)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: file is an incomplete ROM dump\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size & 1023)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: file is an invalid ROM dump\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int l = size;
|
||||||
|
int nb, i;
|
||||||
|
|
||||||
|
/* special MegaCART design by Soeren Gust */
|
||||||
|
if ((l == 32768) || (l == 65536) || (l == 131072) || (l == 262144) || (l == 524288) || (l == 1048576))
|
||||||
|
{
|
||||||
|
app_data.megaxrom = 1;
|
||||||
|
app_data.bank = 1;
|
||||||
|
megarom = malloc(1048576);
|
||||||
|
memcpy(megarom, data, size);
|
||||||
|
|
||||||
|
/* mirror shorter files into full megabyte */
|
||||||
|
if (l < 65536)
|
||||||
|
memcpy(megarom + 32768, megarom, 32768);
|
||||||
|
if (l < 131072)
|
||||||
|
memcpy(megarom + 65536, megarom, 65536);
|
||||||
|
if (l < 262144)
|
||||||
|
memcpy(megarom + 131072, megarom, 131072);
|
||||||
|
if (l < 524288)
|
||||||
|
memcpy(megarom + 262144, megarom, 262144);
|
||||||
|
if (l < 1048576)
|
||||||
|
memcpy(megarom + 524288, megarom, 524288);
|
||||||
|
/* start in bank 0xff */
|
||||||
|
memcpy(&rom_table[0][1024], megarom + 4096 * 255 + 1024, 3072);
|
||||||
|
printf("MegaCart %ldK", l / 1024);
|
||||||
|
nb = 1;
|
||||||
|
}
|
||||||
|
else if (((l % 3072) == 0))
|
||||||
|
{
|
||||||
|
app_data.three_k = 1;
|
||||||
|
nb = l / 3072;
|
||||||
|
|
||||||
|
for (int offset = 0, i = nb - 1; i >= 0; i--, offset += 3072)
|
||||||
|
{
|
||||||
|
memcpy(&rom_table[i][1024], data + offset, 3072);
|
||||||
|
}
|
||||||
|
printf("%dK", nb * 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nb = l / 2048;
|
||||||
|
if ((nb == 2) && (app_data.exrom))
|
||||||
|
{
|
||||||
|
memcpy(&extROM[0], data, 1024);
|
||||||
|
memcpy(&rom_table[0][1024], data + 1024, 3072);
|
||||||
|
printf("3K EXROM");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int offset = 0, i = nb - 1; i >= 0; i--, offset += 2048)
|
||||||
|
{
|
||||||
|
memcpy(&rom_table[i][1024], data + offset, 2048);
|
||||||
|
memcpy(&rom_table[i][3072], &rom_table[i][2048], 1024); /* simulate missing A10 */
|
||||||
|
}
|
||||||
|
printf("%dK", nb * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rom = rom_table[0];
|
||||||
|
if (nb == 1)
|
||||||
|
app_data.bank = 1;
|
||||||
|
else if (nb == 2)
|
||||||
|
app_data.bank = app_data.exrom ? 1 : 2;
|
||||||
|
else if (nb == 4)
|
||||||
|
app_data.bank = 3;
|
||||||
|
else
|
||||||
|
app_data.bank = 4;
|
||||||
|
|
||||||
|
if ((rom_table[nb - 1][1024 + 12] == 'O') && (rom_table[nb - 1][1024 + 13] == 'P') && (rom_table[nb - 1][1024 + 14] == 'N') && (rom_table[nb - 1][1024 + 15] == 'B'))
|
||||||
|
app_data.openb = 1;
|
||||||
|
|
||||||
|
printf(" CRC: %08lX\n", app_data.crc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Score loading/saving by manopac
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "vmachine.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
Calculate Score from given Values
|
||||||
|
Scoretype = abcd:
|
||||||
|
ramtype a = 1: ext ram / 2: int ram
|
||||||
|
valuetype b = 1: 1 Byte each Digit / 2: 1/2 Byte each Digit
|
||||||
|
direct<EFBFBD>on c = 1: higher value digits first / 2: low value digits first
|
||||||
|
count d = number of digits
|
||||||
|
--------------------------------------------------*/
|
||||||
|
int get_score(int scoretype, int scoreaddress)
|
||||||
|
{
|
||||||
|
int score=0;
|
||||||
|
|
||||||
|
if (scoretype!=0)
|
||||||
|
{
|
||||||
|
int position;
|
||||||
|
int i;
|
||||||
|
Byte *RAM;
|
||||||
|
|
||||||
|
int count = scoretype%10;
|
||||||
|
int direction = ((scoretype/10)%10)==1?1:-1;
|
||||||
|
float valuetype = (float) (3-((scoretype/100)%10))/2;
|
||||||
|
int ramtype = scoretype/1000;
|
||||||
|
|
||||||
|
position = scoreaddress+ (direction==1?0:(count*valuetype-1));
|
||||||
|
RAM = ramtype==1?extRAM:intRAM;
|
||||||
|
|
||||||
|
for(i=0;i<count;i++)
|
||||||
|
{
|
||||||
|
score = score*10+((RAM[position+(int)(valuetype*i*direction)]>>(((i+1)%2)*4)*(abs((int) ((valuetype-1)*2))))&15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
Set HighScore into Memory
|
||||||
|
Scoretype = abcd:
|
||||||
|
ramtype a = 1: ext ram / 2: int ram
|
||||||
|
valuetype b = 1: 1 Byte each Digit / 2: 1/2 Byte each Digit
|
||||||
|
direct<EFBFBD>on c = 1: higher value digits first / 2: low value digits first
|
||||||
|
count d = number of digits
|
||||||
|
--------------------------------------------------*/
|
||||||
|
|
||||||
|
void set_score(int scoretype, int scoreaddress, int score)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (scoretype!=0 && score>0)
|
||||||
|
{
|
||||||
|
int position;
|
||||||
|
int i;
|
||||||
|
Byte *RAM;
|
||||||
|
int digit;
|
||||||
|
|
||||||
|
int count = scoretype%10;
|
||||||
|
int direction = ((scoretype/10)%10)==1?-1:1;
|
||||||
|
float valuetype = (float) (3-((scoretype/100)%10))/2;
|
||||||
|
int ramtype = scoretype/1000;
|
||||||
|
|
||||||
|
position = scoreaddress+ (direction==1?0:(count*valuetype-1));
|
||||||
|
RAM = ramtype==1?extRAM:intRAM;
|
||||||
|
|
||||||
|
for(i=count-1;i>=0;i--)
|
||||||
|
{
|
||||||
|
digit = score / power(10,i);
|
||||||
|
RAM[position+(int)(valuetype*i*direction)]=((valuetype==0.5)&&(i%2==0))?(RAM[position+(int)(valuetype*i*direction)]<<4)+digit:digit;
|
||||||
|
score = score - digit*power(10,i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------
|
||||||
|
Save Highscore to File
|
||||||
|
-------------------------------------------------------*/
|
||||||
|
void save_highscore(int highscore,char *scorefile)
|
||||||
|
{
|
||||||
|
FILE *fn;
|
||||||
|
|
||||||
|
highscore = highscore==app_data.default_highscore?0:highscore;
|
||||||
|
|
||||||
|
fn = fopen(scorefile,"w");
|
||||||
|
if (fn==NULL) {
|
||||||
|
fprintf(stderr,"Error opening highscore-file %s: %i\n",scorefile,errno);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fprintf(fn,"%i",highscore)<=0)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Error writing to highscore-file %s: %i\n",scorefile,errno);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************
|
||||||
|
Integer-Implementation of pow
|
||||||
|
***********************************/
|
||||||
|
int power(int base, int higher)
|
||||||
|
{
|
||||||
|
if (higher==0) {
|
||||||
|
return(1);
|
||||||
|
} else if (higher==1) {
|
||||||
|
return(base);
|
||||||
|
} else {
|
||||||
|
int i;
|
||||||
|
int value=base;
|
||||||
|
|
||||||
|
for (i=2;i<=higher;i++)
|
||||||
|
{
|
||||||
|
value = value*base;
|
||||||
|
}
|
||||||
|
return(value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef __SCORE_H
|
||||||
|
#define __SCORE_H
|
||||||
|
|
||||||
|
int get_score(int scoretype, int scoreaddress);
|
||||||
|
void set_score(int scoretype, int scoreaddress, int highscore);
|
||||||
|
void save_highscore(int highscore,char *scorefile);
|
||||||
|
int power(int base, int higher);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef uint8_t Byte;
|
||||||
|
typedef uint16_t ADDRESS;
|
||||||
|
#define MAXC 1024
|
|
@ -0,0 +1,556 @@
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* O2 Video Display Controller emulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "types.h"
|
||||||
|
#include "vmachine.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "cset.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "vpp.h"
|
||||||
|
#include "vdc.h"
|
||||||
|
#include "audio.h"
|
||||||
|
#include "voice.h"
|
||||||
|
#include "bitmap.h"
|
||||||
|
|
||||||
|
#define COL_SP0 0x01
|
||||||
|
#define COL_SP1 0x02
|
||||||
|
#define COL_SP2 0x04
|
||||||
|
#define COL_SP3 0x08
|
||||||
|
#define COL_VGRID 0x10
|
||||||
|
#define COL_HGRID 0x20
|
||||||
|
#define COL_VPP 0x40
|
||||||
|
#define COL_CHAR 0x80
|
||||||
|
|
||||||
|
#define X_START 8
|
||||||
|
#define Y_START 24
|
||||||
|
|
||||||
|
static const uint32_t colortable[2][16] = {
|
||||||
|
/* O2 palette */
|
||||||
|
{0x000000, 0x0e3dd4, 0x00981b, 0x00bbd9, 0xc70008, 0xcc16b3, 0x9d8710,
|
||||||
|
0xe1dee1, 0x5f6e6b, 0x6aa1ff, 0x3df07a, 0x31ffff, 0xff4255, 0xff98ff,
|
||||||
|
0xd9ad5d, 0xffffff},
|
||||||
|
/* VP+ G7400 palette */
|
||||||
|
{0x000000, 0x0000b6, 0x00b600, 0x00b6b6, 0xb60000, 0xb600b6, 0xb6b600,
|
||||||
|
0xb6b6b6, 0x494949, 0x4949ff, 0x49ff49, 0x49ffff, 0xff4949, 0xff49ff,
|
||||||
|
0xffff49, 0xffffff}};
|
||||||
|
|
||||||
|
static Bitmap* bitmap;
|
||||||
|
|
||||||
|
/* Collision buffer */
|
||||||
|
static Byte *col = NULL;
|
||||||
|
|
||||||
|
/* The pointer to the graphics buffer */
|
||||||
|
static Byte *vscreen = NULL;
|
||||||
|
|
||||||
|
static int cached_lines[MAXLINES];
|
||||||
|
|
||||||
|
Byte coltab[256];
|
||||||
|
|
||||||
|
long clip_low;
|
||||||
|
long clip_high;
|
||||||
|
|
||||||
|
int wsize;
|
||||||
|
|
||||||
|
static void create_cmap(void);
|
||||||
|
static void draw_char(Byte ypos, Byte xpos, Byte chr, Byte col);
|
||||||
|
static void draw_quad(Byte ypos, Byte xpos, Byte cp0l, Byte cp0h, Byte cp1l,
|
||||||
|
Byte cp1h, Byte cp2l, Byte cp2h, Byte cp3l, Byte cp3h);
|
||||||
|
static void draw_grid(void);
|
||||||
|
void mputvid(unsigned int ad, unsigned int len, Byte d, Byte c);
|
||||||
|
|
||||||
|
void draw_region(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (regionoff == 0xffff)
|
||||||
|
{
|
||||||
|
i = (master_clk / (LINECNT - 1) - 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = (master_clk / 22 + regionoff);
|
||||||
|
}
|
||||||
|
i = (snapline(i, VDCwrite[0xA0], 0));
|
||||||
|
if (app_data.crc == 0xA7344D1F)
|
||||||
|
{
|
||||||
|
i = (master_clk / 22 + regionoff) + 6;
|
||||||
|
i = (snapline(i, VDCwrite[0xA0], 0) + 6);
|
||||||
|
} /*Atlantis*/
|
||||||
|
|
||||||
|
if (app_data.crc == 0xD0BC4EE6)
|
||||||
|
{
|
||||||
|
i = (master_clk / 24 + regionoff) - 6;
|
||||||
|
i = (snapline(i, VDCwrite[0xA0], 0) + 7);
|
||||||
|
} /*Frogger*/
|
||||||
|
|
||||||
|
if (app_data.crc == 0x26517E77)
|
||||||
|
{
|
||||||
|
i = (master_clk / 22 + regionoff);
|
||||||
|
i = (snapline(i, VDCwrite[0xA0], 0) - 5);
|
||||||
|
} /*Comando Noturno*/
|
||||||
|
|
||||||
|
if (app_data.crc == 0xA57E1724)
|
||||||
|
{
|
||||||
|
i = (master_clk / (LINECNT - 1) - 5);
|
||||||
|
i = (snapline(i, VDCwrite[0xA0], 0) - 3);
|
||||||
|
} /*Catch the ball*/
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
i = 0;
|
||||||
|
clip_low = last_line * (long)BMPW;
|
||||||
|
clip_high = i * (long)BMPW;
|
||||||
|
if (clip_high > BMPW * BMPH)
|
||||||
|
clip_high = BMPW * BMPH;
|
||||||
|
if (clip_low < 0)
|
||||||
|
clip_low = 0;
|
||||||
|
if (clip_low < clip_high)
|
||||||
|
draw_display();
|
||||||
|
last_line = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t colors[256];
|
||||||
|
|
||||||
|
static void create_cmap(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Initialise parts of the colors array */
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
/* Use the color values from the color table */
|
||||||
|
colors[i] = colortable[app_data.vpp ? 1 : 0][i];
|
||||||
|
colors[i + 32] = colors[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 16; i < 32; i++)
|
||||||
|
colors[i] = 0;
|
||||||
|
for (i = 48; i < 256; i++)
|
||||||
|
colors[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearscr(void)
|
||||||
|
{
|
||||||
|
clear(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mputvid(unsigned int ad, unsigned int len, Byte d, Byte c)
|
||||||
|
{
|
||||||
|
if ((ad > (unsigned long)clip_low) && (ad < (unsigned long)clip_high))
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
if (((len & 3) == 0) && (sizeof(unsigned long) == 4))
|
||||||
|
{
|
||||||
|
unsigned long dddd = (((unsigned long)d) & 0xff) | ((((unsigned long)d) & 0xff) << 8) | ((((unsigned long)d) & 0xff) << 16) | ((((unsigned long)d) & 0xff) << 24);
|
||||||
|
unsigned long cccc = (((unsigned long)c) & 0xff) | ((((unsigned long)c) & 0xff) << 8) | ((((unsigned long)c) & 0xff) << 16) | ((((unsigned long)c) & 0xff) << 24);
|
||||||
|
for (i = 0; i<len>> 2; i++)
|
||||||
|
{
|
||||||
|
*((unsigned long *)(vscreen + ad)) = dddd;
|
||||||
|
cccc |= *((unsigned long *)(col + ad));
|
||||||
|
*((unsigned long *)(col + ad)) = cccc;
|
||||||
|
coltab[c] |= ((cccc | (cccc >> 8) | (cccc >> 16) | (cccc >> 24)) & 0xff);
|
||||||
|
ad += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
vscreen[ad] = d;
|
||||||
|
col[ad] |= c;
|
||||||
|
coltab[c] |= col[ad++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_grid(void)
|
||||||
|
{
|
||||||
|
unsigned int pnt, pn1;
|
||||||
|
Byte mask, d;
|
||||||
|
int j, i, x, w;
|
||||||
|
Byte color;
|
||||||
|
|
||||||
|
if (VDCwrite[0xA0] & 0x40)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 9; j++)
|
||||||
|
{
|
||||||
|
pnt = (((j * 24) + 24) * BMPW);
|
||||||
|
for (i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
pn1 = pnt + (i * 32) + 20;
|
||||||
|
color = ColorVector[j * 24 + 24];
|
||||||
|
mputvid(
|
||||||
|
pn1,
|
||||||
|
4,
|
||||||
|
(color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||||
|
color = ColorVector[j * 24 + 25];
|
||||||
|
mputvid(
|
||||||
|
pn1 + BMPW,
|
||||||
|
4,
|
||||||
|
(color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||||
|
color = ColorVector[j * 24 + 26];
|
||||||
|
mputvid(
|
||||||
|
pn1 + BMPW * 2,
|
||||||
|
4,
|
||||||
|
(color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0x01;
|
||||||
|
for (j = 0; j < 9; j++)
|
||||||
|
{
|
||||||
|
pnt = (((j * 24) + 24) * BMPW);
|
||||||
|
for (i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
pn1 = pnt + (i * 32) + 20;
|
||||||
|
if ((pn1 + BMPW * 3 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high))
|
||||||
|
{
|
||||||
|
d = VDCwrite[0xC0 + i];
|
||||||
|
if (j == 8)
|
||||||
|
{
|
||||||
|
d = VDCwrite[0xD0 + i];
|
||||||
|
mask = 1;
|
||||||
|
}
|
||||||
|
if (d & mask)
|
||||||
|
{
|
||||||
|
color = ColorVector[j * 24 + 24];
|
||||||
|
mputvid(
|
||||||
|
pn1,
|
||||||
|
36,
|
||||||
|
(color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||||
|
color = ColorVector[j * 24 + 25];
|
||||||
|
mputvid(
|
||||||
|
pn1 + BMPW,
|
||||||
|
36,
|
||||||
|
(color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||||
|
color = ColorVector[j * 24 + 26];
|
||||||
|
mputvid(
|
||||||
|
pn1 + BMPW * 2,
|
||||||
|
36,
|
||||||
|
(color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_HGRID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask = mask << 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0x01;
|
||||||
|
w = 4;
|
||||||
|
if (VDCwrite[0xA0] & 0x80)
|
||||||
|
{
|
||||||
|
w = 32;
|
||||||
|
}
|
||||||
|
for (j = 0; j < 10; j++)
|
||||||
|
{
|
||||||
|
pnt = (j * 32);
|
||||||
|
mask = 0x01;
|
||||||
|
d = VDCwrite[0xE0 + j];
|
||||||
|
for (x = 0; x < 8; x++)
|
||||||
|
{
|
||||||
|
pn1 = pnt + (((x * 24) + 24) * BMPW) + 20;
|
||||||
|
if (d & mask)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 24; i++)
|
||||||
|
{
|
||||||
|
if ((pn1 >= (unsigned long)clip_low) && (pn1 <= (unsigned long)clip_high))
|
||||||
|
{
|
||||||
|
color = ColorVector[x * 24 + 24 + i];
|
||||||
|
mputvid(
|
||||||
|
pn1,
|
||||||
|
w,
|
||||||
|
(color & 0x07) | ((color & 0x40) >> 3) | (color & 0x80 ? 0 : 8), COL_VGRID);
|
||||||
|
}
|
||||||
|
pn1 += BMPW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask = mask << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_display(void)
|
||||||
|
{
|
||||||
|
vpp_finish_bmp(vscreen, 9, 5, BMPW - 9, BMPH - 5, bitmap->w, bitmap->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blit(uint32_t* dst)
|
||||||
|
{
|
||||||
|
uint8_t* src = vscreen;
|
||||||
|
src += 5 * BMPW;
|
||||||
|
src += 9;
|
||||||
|
for (int j = 0; j < 240; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 320; i++)
|
||||||
|
{
|
||||||
|
*dst++ = colors[*src++];
|
||||||
|
}
|
||||||
|
src += 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_collision(void)
|
||||||
|
{
|
||||||
|
load_colplus(col);
|
||||||
|
coltab[0x01] = coltab[0x02] = 0;
|
||||||
|
coltab[0x04] = coltab[0x08] = 0;
|
||||||
|
coltab[0x10] = coltab[0x20] = 0;
|
||||||
|
coltab[0x40] = coltab[0x80] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_display(void)
|
||||||
|
{
|
||||||
|
int i, j, x, sm, t;
|
||||||
|
Byte y, b, d1, cl, c;
|
||||||
|
|
||||||
|
unsigned int pnt, pnt2;
|
||||||
|
|
||||||
|
for (i = clip_low / BMPW; i < clip_high / BMPW; i++)
|
||||||
|
memset(
|
||||||
|
vscreen + i * BMPW,
|
||||||
|
((ColorVector[i] & 0x38) >> 3) | (ColorVector[i] & 0x80 ? 0 : 8), BMPW);
|
||||||
|
|
||||||
|
if (VDCwrite[0xA0] & 0x08)
|
||||||
|
draw_grid();
|
||||||
|
|
||||||
|
if (useforen && (!(VDCwrite[0xA0] & 0x20)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0x10; i < 0x40; i += 4)
|
||||||
|
draw_char(VDCwrite[i], VDCwrite[i + 1], VDCwrite[i + 2],
|
||||||
|
VDCwrite[i + 3]);
|
||||||
|
|
||||||
|
/* draw quads, position mapping happens in ext_write (vmachine.c)*/
|
||||||
|
for (i = 0x40; i < 0x80; i += 0x10)
|
||||||
|
draw_quad(VDCwrite[i], VDCwrite[i + 1], VDCwrite[i + 2],
|
||||||
|
VDCwrite[i + 3], VDCwrite[i + 6], VDCwrite[i + 7],
|
||||||
|
VDCwrite[i + 10], VDCwrite[i + 11], VDCwrite[i + 14],
|
||||||
|
VDCwrite[i + 15]);
|
||||||
|
|
||||||
|
c = 8;
|
||||||
|
for (i = 12; i >= 0; i -= 4)
|
||||||
|
{
|
||||||
|
pnt2 = 0x80 + (i * 2);
|
||||||
|
y = VDCwrite[i];
|
||||||
|
x = VDCwrite[i + 1] - 8;
|
||||||
|
t = VDCwrite[i + 2];
|
||||||
|
cl = ((t & 0x38) >> 3);
|
||||||
|
cl = ((cl & 2) | ((cl & 1) << 2) | ((cl & 4) >> 2)) + 8;
|
||||||
|
/*174*/
|
||||||
|
if ((x < 164) && (y > 0) && (y < 232))
|
||||||
|
{
|
||||||
|
pnt = y * BMPW + (x * 2) + 20 + sproff;
|
||||||
|
if (t & 4)
|
||||||
|
{
|
||||||
|
if ((pnt + BMPW * 32 >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high))
|
||||||
|
{
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
sm = (((j % 2 == 0) && (((t >> 1) & 1) != (t & 1))) || ((j % 2 == 1) && (t & 1))) ? 1 : 0;
|
||||||
|
d1 = VDCwrite[pnt2++];
|
||||||
|
for (b = 0; b < 8; b++)
|
||||||
|
{
|
||||||
|
if (d1 & 0x01)
|
||||||
|
{
|
||||||
|
if ((x + b + sm < 159) && (y + j < 247))
|
||||||
|
{
|
||||||
|
mputvid(sm + pnt, 4, cl, c);
|
||||||
|
mputvid(sm + pnt + BMPW, 4, cl, c);
|
||||||
|
mputvid(sm + pnt + 2 * BMPW, 4, cl, c);
|
||||||
|
mputvid(sm + pnt + 3 * BMPW, 4, cl, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pnt += 4;
|
||||||
|
d1 = d1 >> 1;
|
||||||
|
}
|
||||||
|
pnt += BMPW * 4 - 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((pnt + BMPW * 16 >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high))
|
||||||
|
{
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
sm = (((j % 2 == 0) && (((t >> 1) & 1) != (t & 1))) || ((j % 2 == 1) && (t & 1))) ? 1 : 0;
|
||||||
|
d1 = VDCwrite[pnt2++];
|
||||||
|
for (b = 0; b < 8; b++)
|
||||||
|
{
|
||||||
|
if (d1 & 0x01)
|
||||||
|
{
|
||||||
|
if ((x + b + sm < 160) && (y + j < 249))
|
||||||
|
{
|
||||||
|
mputvid(sm + pnt, 2, cl, c);
|
||||||
|
mputvid(sm + pnt + BMPW, 2, cl, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pnt += 2;
|
||||||
|
d1 = d1 >> 1;
|
||||||
|
}
|
||||||
|
pnt += BMPW * 2 - 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = c >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_char(Byte ypos, Byte xpos, Byte chr, Byte col)
|
||||||
|
{
|
||||||
|
int j, c;
|
||||||
|
Byte cl, d1;
|
||||||
|
int y, b, n;
|
||||||
|
unsigned int pnt;
|
||||||
|
|
||||||
|
y = (ypos & 0xFE);
|
||||||
|
pnt = y * BMPW + ((xpos - 8) * 2) + 20;
|
||||||
|
|
||||||
|
ypos = ypos >> 1;
|
||||||
|
n = 8 - (ypos % 8) - (chr % 8);
|
||||||
|
if (n < 3)
|
||||||
|
n = n + 7;
|
||||||
|
|
||||||
|
if ((pnt + BMPW * 2 * n >= (unsigned long)clip_low) && (pnt <= (unsigned long)clip_high))
|
||||||
|
{
|
||||||
|
|
||||||
|
c = (int)chr + ypos;
|
||||||
|
if (col & 0x01)
|
||||||
|
c += 256;
|
||||||
|
if (c > 511)
|
||||||
|
c = c - 512;
|
||||||
|
|
||||||
|
cl = ((col & 0x0E) >> 1);
|
||||||
|
cl = ((cl & 2) | ((cl & 1) << 2) | ((cl & 4) >> 2)) + 8;
|
||||||
|
|
||||||
|
if ((y > 0) && (y < 232) && (xpos < 157))
|
||||||
|
{
|
||||||
|
for (j = 0; j < n; j++)
|
||||||
|
{
|
||||||
|
d1 = cset[c + j];
|
||||||
|
for (b = 0; b < 8; b++)
|
||||||
|
{
|
||||||
|
if (d1 & 0x80)
|
||||||
|
{
|
||||||
|
if ((xpos - 8 + b < 160) && (y + j < 240))
|
||||||
|
{
|
||||||
|
mputvid(pnt, 2, cl, COL_CHAR);
|
||||||
|
mputvid(pnt + BMPW, 2, cl, COL_CHAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pnt += 2;
|
||||||
|
d1 = d1 << 1;
|
||||||
|
}
|
||||||
|
pnt += BMPW * 2 - 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This quad drawing routine can display the quad cut off effect used in KTAA.
|
||||||
|
* It needs more testing with other games, especially the clipping.
|
||||||
|
* This code is quite slow and needs a rewrite by somebody with more experience
|
||||||
|
* than I (sgust) have */
|
||||||
|
|
||||||
|
void draw_quad(Byte ypos, Byte xpos, Byte cp0l, Byte cp0h, Byte cp1l, Byte cp1h,
|
||||||
|
Byte cp2l, Byte cp2h, Byte cp3l, Byte cp3h)
|
||||||
|
{
|
||||||
|
/* char set pointers */
|
||||||
|
int chp[4];
|
||||||
|
/* colors */
|
||||||
|
Byte col[4];
|
||||||
|
/* pointer into screen bitmap */
|
||||||
|
unsigned int pnt;
|
||||||
|
/* offset into current line */
|
||||||
|
unsigned int off;
|
||||||
|
/* loop variables */
|
||||||
|
int i, j, lines;
|
||||||
|
|
||||||
|
/* get screen bitmap position of quad */
|
||||||
|
pnt = (ypos & 0xfe) * BMPW + ((xpos - 8) * 2) + 20;
|
||||||
|
/* abort drawing if completely below the bottom clip */
|
||||||
|
if (pnt > (unsigned long)clip_high)
|
||||||
|
return;
|
||||||
|
/* extract and convert char-set offsets */
|
||||||
|
chp[0] = cp0l | ((cp0h & 1) << 8);
|
||||||
|
chp[1] = cp1l | ((cp1h & 1) << 8);
|
||||||
|
chp[2] = cp2l | ((cp2h & 1) << 8);
|
||||||
|
chp[3] = cp3l | ((cp3h & 1) << 8);
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
chp[i] = (chp[i] + (ypos >> 1)) & 0x1ff;
|
||||||
|
lines = 8 - (chp[3] + 1) % 8;
|
||||||
|
/* abort drawing if completely over the top clip */
|
||||||
|
if (pnt + BMPW * 2 * lines < (unsigned long)clip_low)
|
||||||
|
return;
|
||||||
|
/* extract and convert color information */
|
||||||
|
col[0] = (cp0h & 0xe) >> 1;
|
||||||
|
col[1] = (cp1h & 0xe) >> 1;
|
||||||
|
col[2] = (cp2h & 0xe) >> 1;
|
||||||
|
col[3] = (cp3h & 0xe) >> 1;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
col[i] = ((col[i] & 2) | ((col[i] & 1) << 2) | ((col[i] & 4) >> 2)) + 8;
|
||||||
|
/* now draw the quad line by line controlled by the last quad */
|
||||||
|
while (lines-- > 0)
|
||||||
|
{
|
||||||
|
off = 0;
|
||||||
|
/* draw all 4 sub-quads */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
/* draw sub-quad pixel by pixel, but stay in same line */
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
if ((cset[chp[i]] & (1 << (7 - j))) && (off < BMPW))
|
||||||
|
{
|
||||||
|
mputvid(pnt + off, 2, col[i], COL_CHAR);
|
||||||
|
mputvid(pnt + off + BMPW, 2, col[i], COL_CHAR);
|
||||||
|
}
|
||||||
|
/* next pixel */
|
||||||
|
off += 2;
|
||||||
|
}
|
||||||
|
/* space between sub-quads */
|
||||||
|
off += 16;
|
||||||
|
}
|
||||||
|
/* advance char-set pointers */
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
chp[i] = (chp[i] + 1) & 0x1ff;
|
||||||
|
/* advance screen bitmap pointer */
|
||||||
|
pnt += BMPW * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_display(void)
|
||||||
|
{
|
||||||
|
create_cmap();
|
||||||
|
bitmap = NewBitmap(BMPW, BMPH);
|
||||||
|
if (!bitmap)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not allocate memory for screen buffer.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
vscreen = (Byte *)bitmap->dat;
|
||||||
|
clear(bitmap);
|
||||||
|
col = (Byte *)malloc(BMPW * BMPH);
|
||||||
|
if (!col)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not allocate memory for collision buffer.\n");
|
||||||
|
free(vscreen);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
memset(col, 0, BMPW * BMPH);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef __VDC_H
|
||||||
|
#define __VDC_H
|
||||||
|
|
||||||
|
#define BMPW 340
|
||||||
|
#define BMPH 250
|
||||||
|
#define WNDW 320
|
||||||
|
#define WNDH 240
|
||||||
|
|
||||||
|
#define BOX_W MIN(512, SCREEN_W-16)
|
||||||
|
#define BOX_H MIN(256, (SCREEN_H-64)&0xFFF0)
|
||||||
|
|
||||||
|
#define BOX_L ((SCREEN_W - BOX_W) / 2)
|
||||||
|
#define BOX_R ((SCREEN_W + BOX_W) / 2)
|
||||||
|
#define BOX_T ((SCREEN_H - BOX_H) / 2)
|
||||||
|
#define BOX_B ((SCREEN_H + BOX_H) / 2)
|
||||||
|
|
||||||
|
extern Byte coltab[];
|
||||||
|
extern long clip_low;
|
||||||
|
extern long clip_high;
|
||||||
|
|
||||||
|
void init_display(void);
|
||||||
|
void draw_display(void);
|
||||||
|
void draw_region(void);
|
||||||
|
void finish_display();
|
||||||
|
void clear_collision(void);
|
||||||
|
void clearscr(void);
|
||||||
|
|
||||||
|
void blit(uint32_t* dst);
|
||||||
|
#endif
|
|
@ -0,0 +1,746 @@
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Main O2 machine emulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "audio.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "vdc.h"
|
||||||
|
#include "vpp.h"
|
||||||
|
#include "voice.h"
|
||||||
|
#include "vmachine.h"
|
||||||
|
|
||||||
|
static Byte x_latch, y_latch;
|
||||||
|
static int romlatch = 0;
|
||||||
|
static Byte line_count;
|
||||||
|
static int fps = FPS_NTSC;
|
||||||
|
|
||||||
|
static Byte snapedlines[MAXLINES + 2 * MAXSNAP][256][2];
|
||||||
|
|
||||||
|
int evblclk = EVBLCLK_NTSC;
|
||||||
|
|
||||||
|
struct resource app_data;
|
||||||
|
int frame = 0;
|
||||||
|
|
||||||
|
int int_clk; /* counter for length of /INT pulses */
|
||||||
|
int master_clk; /* Master clock */
|
||||||
|
int h_clk; /* horizontal clock */
|
||||||
|
unsigned long clk_counter;
|
||||||
|
int last_line;
|
||||||
|
int key2vcnt = 0;
|
||||||
|
int mstate;
|
||||||
|
|
||||||
|
int pendirq = 0;
|
||||||
|
int enahirq = 1;
|
||||||
|
int useforen = 0;
|
||||||
|
long regionoff = 0xffff;
|
||||||
|
int mxsnap = 2;
|
||||||
|
int sproff = 0;
|
||||||
|
int tweakedaudio = 0;
|
||||||
|
|
||||||
|
Byte rom_table[8][4096];
|
||||||
|
|
||||||
|
Byte intRAM[64];
|
||||||
|
Byte extRAM[256];
|
||||||
|
Byte extROM[1024];
|
||||||
|
Byte VDCwrite[256];
|
||||||
|
Byte ColorVector[MAXLINES];
|
||||||
|
Byte AudioVector[MAXLINES];
|
||||||
|
Byte *rom;
|
||||||
|
Byte *megarom;
|
||||||
|
|
||||||
|
int key2[128];
|
||||||
|
|
||||||
|
static void do_kluges(void);
|
||||||
|
static void setvideomode(int t);
|
||||||
|
|
||||||
|
void handle_vbl(void)
|
||||||
|
{
|
||||||
|
update_audio();
|
||||||
|
update_voice();
|
||||||
|
draw_region();
|
||||||
|
ext_IRQ();
|
||||||
|
mstate = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_evbl(void)
|
||||||
|
{
|
||||||
|
static long last = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
last_line = 0;
|
||||||
|
master_clk -= evblclk;
|
||||||
|
frame++;
|
||||||
|
finish_display();
|
||||||
|
|
||||||
|
if (app_data.crc == 0xA7344D1F)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 140; i++)
|
||||||
|
{
|
||||||
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
|
||||||
|
AudioVector[i] = VDCwrite[0xAA];
|
||||||
|
}
|
||||||
|
} /*Atlantis*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < MAXLINES; i++)
|
||||||
|
{
|
||||||
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
|
||||||
|
AudioVector[i] = VDCwrite[0xAA];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (key2vcnt++ > 10)
|
||||||
|
{
|
||||||
|
key2vcnt = 0;
|
||||||
|
for (i = 0; i < 128; i++)
|
||||||
|
key2[i] = 0;
|
||||||
|
}
|
||||||
|
mstate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_evbll(void)
|
||||||
|
{
|
||||||
|
static long last = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/******************* 150 */
|
||||||
|
|
||||||
|
for (i = 150; i < MAXLINES; i++)
|
||||||
|
{
|
||||||
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
|
||||||
|
AudioVector[i] = VDCwrite[0xAA];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key2vcnt++ > 10)
|
||||||
|
{
|
||||||
|
key2vcnt = 0;
|
||||||
|
for (i = 0; i < 128; i++)
|
||||||
|
key2[i] = 0;
|
||||||
|
}
|
||||||
|
mstate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_system(void)
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
last_line = 0;
|
||||||
|
mstate = 0;
|
||||||
|
master_clk = 0;
|
||||||
|
h_clk = 0;
|
||||||
|
line_count = 0;
|
||||||
|
itimer = 0;
|
||||||
|
clk_counter = 0;
|
||||||
|
init_roms();
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
VDCwrite[i] = 0;
|
||||||
|
extRAM[i] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
intRAM[i] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < MAXLINES; i++)
|
||||||
|
AudioVector[i] = ColorVector[i] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXLINES + 2 * MAXSNAP; i++)
|
||||||
|
for (j = 0; j < 256; j++)
|
||||||
|
for (k = 0; k < 2; k++)
|
||||||
|
snapedlines[i][j][k] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 128; i++)
|
||||||
|
key2[i] = 0;
|
||||||
|
key2vcnt = 0;
|
||||||
|
if (app_data.euro)
|
||||||
|
setvideomode(1);
|
||||||
|
else
|
||||||
|
setvideomode(0);
|
||||||
|
do_kluges();
|
||||||
|
init_vpp();
|
||||||
|
clear_collision();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_roms(void)
|
||||||
|
{
|
||||||
|
rom = rom_table[0];
|
||||||
|
romlatch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte read_t1(void)
|
||||||
|
{
|
||||||
|
/*17*/
|
||||||
|
if ((h_clk > 16) || (master_clk > VBLCLK))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_p1(Byte d)
|
||||||
|
{
|
||||||
|
if ((d & 0x80) != (p1 & 0x80))
|
||||||
|
{
|
||||||
|
int i, l;
|
||||||
|
l = snapline((int)((float)master_clk / 22.0 + 0.1), VDCwrite[0xA3],
|
||||||
|
1);
|
||||||
|
for (i = l; i < MAXLINES; i++)
|
||||||
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (d & 0x80);
|
||||||
|
}
|
||||||
|
p1 = d;
|
||||||
|
if (app_data.bank == 2)
|
||||||
|
{
|
||||||
|
rom = rom_table[~p1 & 0x01];
|
||||||
|
}
|
||||||
|
else if (app_data.bank == 3)
|
||||||
|
{
|
||||||
|
rom = rom_table[~p1 & 0x03];
|
||||||
|
}
|
||||||
|
else if (app_data.bank == 4)
|
||||||
|
{
|
||||||
|
rom = rom_table[(p1 & 1) ? 0 : romlatch];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte read_P2(void)
|
||||||
|
{
|
||||||
|
int i, si, so, km;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
// TODO
|
||||||
|
/*if (NeedsPoll)
|
||||||
|
poll_keyboard();
|
||||||
|
|
||||||
|
if (!(p1 & 0x04))
|
||||||
|
{
|
||||||
|
si = (p2 & 7);
|
||||||
|
so = 0xff;
|
||||||
|
if (si < 6)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
km = key_map[si][i];
|
||||||
|
if ((key[km] && ((!joykeystab[km]) || (key_shifts & KB_CAPSLOCK_FLAG))) || (key2[km]))
|
||||||
|
{
|
||||||
|
so = i ^ 0x07;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (so != 0xff)
|
||||||
|
{
|
||||||
|
p2 = p2 & 0x0F;
|
||||||
|
p2 = p2 | (so << 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p2 = p2 | 0xF0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p2 = p2 | 0xF0;
|
||||||
|
}
|
||||||
|
return (p2);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte ext_read(ADDRESS adr)
|
||||||
|
{
|
||||||
|
Byte d;
|
||||||
|
Byte si;
|
||||||
|
Byte m;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(p1 & 0x08) && !(p1 & 0x40))
|
||||||
|
{
|
||||||
|
/* Handle VDC Read */
|
||||||
|
switch (adr)
|
||||||
|
{
|
||||||
|
case 0xA1:
|
||||||
|
d = VDCwrite[0xA0] & 0x02;
|
||||||
|
if (master_clk > VBLCLK)
|
||||||
|
d = d | 0x08;
|
||||||
|
if (h_clk < (LINECNT - 7))
|
||||||
|
d = d | 0x01;
|
||||||
|
if (sound_IRQ)
|
||||||
|
d = d | 0x04;
|
||||||
|
sound_IRQ = 0;
|
||||||
|
return d;
|
||||||
|
case 0xA2:
|
||||||
|
si = VDCwrite[0xA2];
|
||||||
|
m = 0x01;
|
||||||
|
d = 0;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (si & m)
|
||||||
|
{
|
||||||
|
if (coltab[1] & m)
|
||||||
|
d = d | (coltab[1] & (m ^ 0xFF));
|
||||||
|
if (coltab[2] & m)
|
||||||
|
d = d | (coltab[2] & (m ^ 0xFF));
|
||||||
|
if (coltab[4] & m)
|
||||||
|
d = d | (coltab[4] & (m ^ 0xFF));
|
||||||
|
if (coltab[8] & m)
|
||||||
|
d = d | (coltab[8] & (m ^ 0xFF));
|
||||||
|
if (coltab[0x10] & m)
|
||||||
|
d = d | (coltab[0x10] & (m ^ 0xFF));
|
||||||
|
if (coltab[0x20] & m)
|
||||||
|
d = d | (coltab[0x20] & (m ^ 0xFF));
|
||||||
|
if (coltab[0x80] & m)
|
||||||
|
d = d | (coltab[0x80] & (m ^ 0xFF));
|
||||||
|
}
|
||||||
|
m = m << 1;
|
||||||
|
}
|
||||||
|
clear_collision();
|
||||||
|
return d;
|
||||||
|
case 0xA5:
|
||||||
|
if (!(VDCwrite[0xA0] & 0x02))
|
||||||
|
{
|
||||||
|
return x_latch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x_latch = h_clk * 12;
|
||||||
|
return x_latch;
|
||||||
|
}
|
||||||
|
case 0xA4:
|
||||||
|
if (!(VDCwrite[0xA0] & 0x02))
|
||||||
|
{
|
||||||
|
return y_latch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y_latch = master_clk / 22;
|
||||||
|
if (y_latch > 241)
|
||||||
|
y_latch = 0xFF;
|
||||||
|
return y_latch;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return VDCwrite[adr];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!(p1 & 0x10))
|
||||||
|
{
|
||||||
|
/* Handle ext RAM Read */
|
||||||
|
if (app_data.megaxrom && (adr >= 0x80))
|
||||||
|
{
|
||||||
|
/* MegaCART registers are mirrored every 4 bytes */
|
||||||
|
if ((adr & 0x83) == 0x83)
|
||||||
|
{
|
||||||
|
/* TODO: emulate EEPROM data in */
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return extRAM[adr & 0x83];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return extRAM[adr & 0xFF];
|
||||||
|
}
|
||||||
|
else if (!(p1 & 0x20))
|
||||||
|
{
|
||||||
|
/* Read a Videopac+ register */
|
||||||
|
return vpp_read(adr);
|
||||||
|
}
|
||||||
|
else if (app_data.exrom && (p1 & 0x02))
|
||||||
|
{
|
||||||
|
/* Handle read from exrom */
|
||||||
|
return extROM[(p2 << 8) | (adr & 0xFF)];
|
||||||
|
}
|
||||||
|
else if (app_data.megaxrom && !(p1 & 0x02) && !(p1 & 0x40))
|
||||||
|
{
|
||||||
|
/* Handle data read from MegaCART */
|
||||||
|
return megarom[(extRAM[0x81] << 12) | ((p2 & 0x0f) << 8) | (adr & 0xff)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte in_bus(void)
|
||||||
|
{
|
||||||
|
Byte si = 0, d = 0, mode = 0, jn = 0, sticknum = 0;
|
||||||
|
|
||||||
|
if ((p1 & 0x08) && (p1 & 0x10))
|
||||||
|
{
|
||||||
|
/* Handle joystick read */
|
||||||
|
if (!(p1 & 0x04))
|
||||||
|
{
|
||||||
|
si = (p2 & 7);
|
||||||
|
}
|
||||||
|
d = 0xFF;
|
||||||
|
// si == 1 => joystick 0
|
||||||
|
// si != 1 => joystick 1
|
||||||
|
// &= 0xfe up
|
||||||
|
// &= 0xfd right
|
||||||
|
// &= 0xfb down
|
||||||
|
// &= 0xf7 left
|
||||||
|
// &= 0xef both (?) buttons
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ext_write(Byte dat, ADDRESS adr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(p1 & 0x08))
|
||||||
|
{
|
||||||
|
/* Handle VDC Write */
|
||||||
|
if (adr == 0xA0)
|
||||||
|
{
|
||||||
|
if ((VDCwrite[0xA0] & 0x02) && !(dat & 0x02))
|
||||||
|
{
|
||||||
|
y_latch = master_clk / 22;
|
||||||
|
x_latch = h_clk * 12;
|
||||||
|
if (y_latch > 241)
|
||||||
|
y_latch = 0xFF;
|
||||||
|
}
|
||||||
|
if ((master_clk <= VBLCLK) && (VDCwrite[0xA0] != dat))
|
||||||
|
{
|
||||||
|
draw_region();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (adr == 0xA3)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
l = snapline((int)((float)master_clk / 22.0 + 0.5), dat, 1);
|
||||||
|
for (i = l; i < MAXLINES; i++)
|
||||||
|
ColorVector[i] = (dat & 0x7f) | (p1 & 0x80);
|
||||||
|
}
|
||||||
|
else if (adr == 0xAA)
|
||||||
|
{
|
||||||
|
for (i = master_clk / 22; i < MAXLINES; i++)
|
||||||
|
AudioVector[i] = dat;
|
||||||
|
}
|
||||||
|
else if ((adr >= 0x40) && (adr <= 0x7f) && ((adr & 2) == 0))
|
||||||
|
{
|
||||||
|
/* simulate quad: all 4 sub quad position registers
|
||||||
|
* are mapped to the same internal register */
|
||||||
|
adr = adr & 0x71;
|
||||||
|
/* Another minor thing: the y register always returns
|
||||||
|
* bit 0 as 0 */
|
||||||
|
if ((adr & 1) == 0)
|
||||||
|
dat = dat & 0xfe;
|
||||||
|
VDCwrite[adr] = VDCwrite[adr + 4] = VDCwrite[adr + 8] = VDCwrite[adr + 12] = dat;
|
||||||
|
}
|
||||||
|
VDCwrite[adr] = dat;
|
||||||
|
}
|
||||||
|
else if (!(p1 & 0x10) && !(p1 & 0x40))
|
||||||
|
{
|
||||||
|
adr = adr & 0xFF;
|
||||||
|
|
||||||
|
if (adr < 0x80)
|
||||||
|
{
|
||||||
|
/* Handle ext RAM Write */
|
||||||
|
extRAM[adr] = dat;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (app_data.bank == 4)
|
||||||
|
{
|
||||||
|
romlatch = (~dat) & 7;
|
||||||
|
rom = rom_table[(p1 & 1) ? 0 : romlatch];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle The Voice */
|
||||||
|
if (!(dat & 0x20))
|
||||||
|
reset_voice();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (adr == 0xE4)
|
||||||
|
set_voice_bank(0);
|
||||||
|
else if ((adr >= 0xE8) && (adr <= 0xEF))
|
||||||
|
set_voice_bank(adr - 0xE7);
|
||||||
|
else if (((adr >= 0x80) && (adr <= 0xDF)) || ((adr >= 0xF0) && (adr <= 0xFF)))
|
||||||
|
trigger_voice(adr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!(p1 & 0x20))
|
||||||
|
{
|
||||||
|
/* Write to a Videopac+ register */
|
||||||
|
vpp_write(dat, adr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_kluges(void)
|
||||||
|
{
|
||||||
|
if (app_data.crc == 0xA7344D1F)
|
||||||
|
pendirq = 1; /* Atlantis */
|
||||||
|
if (app_data.crc == 0xFB83171E)
|
||||||
|
pendirq = 1; /* Blockout */
|
||||||
|
if (app_data.crc == 0xD38153F6)
|
||||||
|
pendirq = 1; /* Blockout (french) */
|
||||||
|
if (app_data.crc == 0x881CEAE4)
|
||||||
|
pendirq = 1; /* Wall Street */
|
||||||
|
|
||||||
|
if (app_data.crc == 0x9E42E766)
|
||||||
|
useforen = 1; /* Turtles */
|
||||||
|
if (app_data.crc == 0x1C750349)
|
||||||
|
useforen = 1; /* Turtles (European version) */
|
||||||
|
if (app_data.crc == 0x202F2749)
|
||||||
|
useforen = 1; /* Q*bert */
|
||||||
|
if (app_data.crc == 0x06861A9C)
|
||||||
|
useforen = 1; /* Flashpoint 5 (Videopac adaption) */
|
||||||
|
|
||||||
|
if (app_data.crc == 0xFB83171E)
|
||||||
|
enahirq = 0; /* Blockout*/
|
||||||
|
if (app_data.crc == 0xD38153F6)
|
||||||
|
enahirq = 0; /* Blockout (french) */
|
||||||
|
|
||||||
|
if (app_data.crc == 0xFB83171E)
|
||||||
|
regionoff = 1; /* Blockout*/
|
||||||
|
if (app_data.crc == 0xD38153F6)
|
||||||
|
regionoff = 1; /* Blockout (french) */
|
||||||
|
if (app_data.crc == 0x202F2749)
|
||||||
|
regionoff = 0; /* Q*bert */
|
||||||
|
if (app_data.crc == 0x5216771A)
|
||||||
|
regionoff = 1; /* Popeye */
|
||||||
|
if (app_data.crc == 0x0C2E4811)
|
||||||
|
regionoff = 11; /* Out of this World! / Helicopter Rescue! */
|
||||||
|
if (app_data.crc == 0x67069924)
|
||||||
|
regionoff = 11; /* Smithereens! */
|
||||||
|
if (app_data.crc == 0x44D1A8A5)
|
||||||
|
regionoff = 11; /* Smithereens! (European version) */
|
||||||
|
if (app_data.crc == 0x2391C2FB)
|
||||||
|
regionoff = 11; /* Smithereens! + */
|
||||||
|
if (app_data.crc == 0xBB4AD548)
|
||||||
|
regionoff = 11; /* Smithereens! modified 1 */
|
||||||
|
if (app_data.crc == 0x25057C11)
|
||||||
|
regionoff = 11; /* Smithereens! modified 2 */
|
||||||
|
if (app_data.crc == 0xB936BD78)
|
||||||
|
regionoff = 12; /* Type & Tell */
|
||||||
|
if (app_data.crc == 0xAD8B9AE0)
|
||||||
|
regionoff = 2; /* Type & Tell modified 1 */
|
||||||
|
if (app_data.crc == 0x5C02BEE6)
|
||||||
|
regionoff = 2; /* Type & Tell modified 2 */
|
||||||
|
if (app_data.crc == 0xDC30AD3D)
|
||||||
|
regionoff = 10; /* Dynasty! */
|
||||||
|
if (app_data.crc == 0x7810BAD5)
|
||||||
|
regionoff = 8; /* Dynasty! (European) */
|
||||||
|
if (app_data.crc == 0xA7344D1F)
|
||||||
|
regionoff = 0; /* Atlantis */
|
||||||
|
if (app_data.crc == 0xD0BC4EE6)
|
||||||
|
regionoff = 12; /* Frogger */
|
||||||
|
if (app_data.crc == 0xA57D84F3)
|
||||||
|
regionoff = 8; /* Frogger BR */
|
||||||
|
if (app_data.crc == 0x825976A9)
|
||||||
|
regionoff = 0; /* Mousing Cat 8kb */
|
||||||
|
if (app_data.crc == 0xF390BFEC)
|
||||||
|
regionoff = 0; /* Mousing Cat 4kb */
|
||||||
|
if (app_data.crc == 0x61A350E6)
|
||||||
|
regionoff = 0; /* Mousing Cat (french) */
|
||||||
|
if (app_data.crc == 0x3BFEF56B)
|
||||||
|
regionoff = 1; /* Four in 1 Row! */
|
||||||
|
if (app_data.crc == 0x7C747245)
|
||||||
|
regionoff = 1; /* Four in 1 Row! modified */
|
||||||
|
if (app_data.crc == 0x9B5E9356)
|
||||||
|
regionoff = 1; /* Four in 1 Row! (french) */
|
||||||
|
|
||||||
|
if (app_data.crc == 0x6CEBAB74)
|
||||||
|
regionoff = 12; /* P.T. Barnum's Acrobats! (European version) */
|
||||||
|
if (app_data.crc == 0xE7B26A56)
|
||||||
|
regionoff = 12; /* P.T. Barnum's Acrobats! (European version - Extra keys) */
|
||||||
|
|
||||||
|
if (app_data.crc == 0xFB83171E)
|
||||||
|
mxsnap = 3; /* Blockout*/
|
||||||
|
if (app_data.crc == 0xD38153F6)
|
||||||
|
mxsnap = 3; /* Blockout (french) */
|
||||||
|
if (app_data.crc == 0xA57E1724)
|
||||||
|
mxsnap = 12; /* Catch the Ball / Noughts and Crosses */
|
||||||
|
if (app_data.crc == 0xBE4FF48E)
|
||||||
|
mxsnap = 12; /* Catch the Ball / Noughts and Crosses modified */
|
||||||
|
if (app_data.crc == 0xFD179F6D)
|
||||||
|
mxsnap = 3; /* Clay Pigeon! */
|
||||||
|
if (app_data.crc == 0x9C9DDDF9)
|
||||||
|
mxsnap = 3; /* Verkehr */
|
||||||
|
if (app_data.crc == 0x95936B07)
|
||||||
|
mxsnap = 3; /* Super Cobra */
|
||||||
|
if (app_data.crc == 0x881CEAE4)
|
||||||
|
mxsnap = 3; /* Wall Street */
|
||||||
|
if (app_data.crc == 0x9E42E766)
|
||||||
|
mxsnap = 0; /* Turtles */
|
||||||
|
if (app_data.crc == 0x1C750349)
|
||||||
|
mxsnap = 0; /* Turtles (European version) */
|
||||||
|
if (app_data.crc == 0xD0BC4EE6)
|
||||||
|
mxsnap = 3; /* Frogger */
|
||||||
|
if (app_data.crc == 0xA57D84F3)
|
||||||
|
mxsnap = 3; /* Frogger BR */
|
||||||
|
if (app_data.crc == 0x3BFEF56B)
|
||||||
|
mxsnap = 6; /* Four in 1 Row! */
|
||||||
|
if (app_data.crc == 0x9B5E9356)
|
||||||
|
mxsnap = 6; /* Four in 1 Row! (french) */
|
||||||
|
if (app_data.crc == 0x7C747245)
|
||||||
|
mxsnap = 6; /* Four in 1 Row! modified */
|
||||||
|
|
||||||
|
if (app_data.crc == 0xA7344D1F)
|
||||||
|
setvideomode(1); /* Atlantis */
|
||||||
|
if (app_data.crc == 0x39E31BF0)
|
||||||
|
setvideomode(1); /* Jake */
|
||||||
|
if (app_data.crc == 0x92D0177B)
|
||||||
|
setvideomode(1); /* Jake (hack) */
|
||||||
|
if (app_data.crc == 0x3351FEDA)
|
||||||
|
setvideomode(1); /* Power Lords */
|
||||||
|
if (app_data.crc == 0x40AE062D)
|
||||||
|
setvideomode(1); /* Power Lords (alternate) */
|
||||||
|
if (app_data.crc == 0xD158EEBA)
|
||||||
|
setvideomode(1); /* Labirinth */
|
||||||
|
if (app_data.crc == 0x26B0FF5B)
|
||||||
|
setvideomode(1); /* Nightmare */
|
||||||
|
if (app_data.crc == 0xDF36683F)
|
||||||
|
setvideomode(1); /* Shark Hunter */
|
||||||
|
if (app_data.crc == 0xAF307559)
|
||||||
|
setvideomode(1); /* Super Bee 8Kb */
|
||||||
|
if (app_data.crc == 0x9585D511)
|
||||||
|
setvideomode(1); /* Super Bee 4Kb */
|
||||||
|
if (app_data.crc == 0x58FA6766)
|
||||||
|
setvideomode(1); /* War of the Nerves */
|
||||||
|
if (app_data.crc == 0x58FA6766)
|
||||||
|
setvideomode(1); /* War of the Nerves */
|
||||||
|
if (app_data.crc == 0x39989464)
|
||||||
|
setvideomode(1); /* Hockey! / Soccer! */
|
||||||
|
if (app_data.crc == 0x3BFEF56B)
|
||||||
|
setvideomode(1); /* Four in 1 Row! */
|
||||||
|
if (app_data.crc == 0x9B5E9356)
|
||||||
|
setvideomode(1); /* Four in 1 Row! (french) */
|
||||||
|
if (app_data.crc == 0x7C747245)
|
||||||
|
setvideomode(1); /* Four in 1 Row! modified */
|
||||||
|
if (app_data.crc == 0x68560DC7)
|
||||||
|
setvideomode(1); /* Jopac Moto Crash */
|
||||||
|
if (app_data.crc == 0x020FCA15)
|
||||||
|
setvideomode(1); /* Jopac Moto Crash modified (non VP+) */
|
||||||
|
if (app_data.crc == 0xC4134DF8)
|
||||||
|
setvideomode(1); /* Helicopter Rescue + */
|
||||||
|
if (app_data.crc == 0x0D2D721D)
|
||||||
|
setvideomode(1); /* Trans American Rally + */
|
||||||
|
if (app_data.crc == 0x9D72D4E9)
|
||||||
|
setvideomode(1); /* Blobbers */
|
||||||
|
if (app_data.crc == 0xB2F0F0B4)
|
||||||
|
setvideomode(1); /* Le Tresor Englouti + */
|
||||||
|
if (app_data.crc == 0x0B2DEB61)
|
||||||
|
setvideomode(1); /* Tutankham */
|
||||||
|
if (app_data.crc == 0x313547EB)
|
||||||
|
setvideomode(1); /* VP53 */
|
||||||
|
if (app_data.crc == 0x06861A9C)
|
||||||
|
setvideomode(1); /* Flashpoint 5 (Videopac adaption) */
|
||||||
|
if (app_data.crc == 0xA57E1724)
|
||||||
|
setvideomode(0); /* Catch the Ball / Noughts and Crosses */
|
||||||
|
if (app_data.crc == 0xBE4FF48E)
|
||||||
|
setvideomode(0); /* Catch the Ball / Noughts and Crosses modified */
|
||||||
|
if (app_data.crc == 0xFB83171E)
|
||||||
|
setvideomode(0); /* Blockout*/
|
||||||
|
if (app_data.crc == 0xD38153F6)
|
||||||
|
setvideomode(0); /* Blockout (french) */
|
||||||
|
if (app_data.crc == 0x9BFC3E01)
|
||||||
|
setvideomode(0); /* Demon Attack */
|
||||||
|
if (app_data.crc == 0x50AF9D45)
|
||||||
|
setvideomode(0); /* Demon Attack + */
|
||||||
|
if (app_data.crc == 0x9884EF36)
|
||||||
|
setvideomode(0); /* Demon Attack + modified */
|
||||||
|
if (app_data.crc == 0x4A578DFE)
|
||||||
|
setvideomode(0); /* Restaurant ntsc */
|
||||||
|
if (app_data.crc == 0x863D5E2D)
|
||||||
|
setvideomode(0); /* Shark Hunter ntsc */
|
||||||
|
|
||||||
|
if (app_data.crc == 0xD62814A3)
|
||||||
|
evblclk = 12000; /* Pick Axe Pete */
|
||||||
|
if (app_data.crc == 0xB2FFB353)
|
||||||
|
evblclk = 12000; /* Pick Axe Pete + */
|
||||||
|
if (app_data.crc == 0x81C20196)
|
||||||
|
evblclk = 12000; /* Pick Axe Pete + (modified) */
|
||||||
|
|
||||||
|
if ((app_data.crc == 0xF390BFEC) || (app_data.crc == 0x825976A9) || (app_data.crc == 0x61A350E6))
|
||||||
|
{ /* Mousing Cat */
|
||||||
|
setvideomode(1);
|
||||||
|
evblclk = 7642;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app_data.crc == 0xD0BC4EE6)
|
||||||
|
{ /* Frogger */
|
||||||
|
setvideomode(1);
|
||||||
|
evblclk = 7642;
|
||||||
|
}
|
||||||
|
if (app_data.crc == 0x26517E77)
|
||||||
|
{ /* Commando Noturno */
|
||||||
|
setvideomode(1);
|
||||||
|
evblclk = 6100;
|
||||||
|
regionoff = 12;
|
||||||
|
}
|
||||||
|
if (app_data.crc == 0xA57E1724)
|
||||||
|
{ /* Catch the ball*/
|
||||||
|
regionoff = 5;
|
||||||
|
sproff = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((app_data.crc == 0x2DCB77F0) || (app_data.crc == 0xF6882734))
|
||||||
|
{ /* Depth Charge / Marksman */
|
||||||
|
setvideomode(1);
|
||||||
|
evblclk = 8000;
|
||||||
|
}
|
||||||
|
if (app_data.crc == 0x881CEAE4)
|
||||||
|
{ /* Wall Street */
|
||||||
|
setvideomode(1);
|
||||||
|
evblclk = 6100;
|
||||||
|
}
|
||||||
|
if (app_data.crc == 0xD0BC4EE6)
|
||||||
|
tweakedaudio = 1; /* Frogger */
|
||||||
|
if (app_data.crc == 0xA57D84F3)
|
||||||
|
tweakedaudio = 1; /* Frogger BR */
|
||||||
|
if (app_data.crc == 0x5216771A)
|
||||||
|
tweakedaudio = 1; /* Popeye */
|
||||||
|
if (app_data.crc == 0xAFB23F89)
|
||||||
|
tweakedaudio = 1; /* Musician */
|
||||||
|
if (app_data.crc == 0xC4134DF8)
|
||||||
|
tweakedaudio = 1; /* Helicopter Rescue + */
|
||||||
|
if (app_data.crc == 0x0D2D721D)
|
||||||
|
tweakedaudio = 1; /* Trans American Rally + */
|
||||||
|
|
||||||
|
if (app_data.crc == 0xD3B09FEC)
|
||||||
|
sproff = 1; /* Volleyball! */
|
||||||
|
if (app_data.crc == 0x551E38A2)
|
||||||
|
sproff = 1; /* Volleyball! (french) */
|
||||||
|
}
|
||||||
|
|
||||||
|
int snapline(int pos, Byte reg, int t)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (pos < MAXLINES + MAXSNAP + MAXSNAP)
|
||||||
|
{
|
||||||
|
for (i = 0; i < mxsnap; i++)
|
||||||
|
{
|
||||||
|
if (snapedlines[pos + MAXSNAP - i][reg][t])
|
||||||
|
return pos - i;
|
||||||
|
if (snapedlines[pos + MAXSNAP + i][reg][t])
|
||||||
|
return pos + i;
|
||||||
|
}
|
||||||
|
snapedlines[pos + MAXSNAP][reg][t] = 1;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setvideomode(int t)
|
||||||
|
{
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
evblclk = EVBLCLK_PAL;
|
||||||
|
fps = FPS_PAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evblclk = EVBLCLK_NTSC;
|
||||||
|
fps = FPS_NTSC;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
#ifndef VMACHINE_H
|
||||||
|
#define VMACHINE_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define LINECNT 21
|
||||||
|
#define MAXLINES 500
|
||||||
|
#define MAXSNAP 50
|
||||||
|
|
||||||
|
#define VBLCLK 5493
|
||||||
|
#define EVBLCLK_NTSC 5964
|
||||||
|
#define EVBLCLK_PAL 7259
|
||||||
|
|
||||||
|
#define FPS_NTSC 60
|
||||||
|
#define FPS_PAL 50
|
||||||
|
|
||||||
|
extern int last_line;
|
||||||
|
|
||||||
|
extern int evblclk;
|
||||||
|
|
||||||
|
extern int master_clk; /* Master clock */
|
||||||
|
extern int int_clk; /* counter for length of /INT pulses for JNI */
|
||||||
|
extern int h_clk; /* horizontal clock */
|
||||||
|
extern Byte coltab[256];
|
||||||
|
extern int mstate;
|
||||||
|
|
||||||
|
extern Byte rom_table[8][4096];
|
||||||
|
extern Byte intRAM[];
|
||||||
|
extern Byte extRAM[];
|
||||||
|
extern Byte extROM[];
|
||||||
|
extern Byte VDCwrite[256];
|
||||||
|
extern Byte ColorVector[MAXLINES];
|
||||||
|
extern Byte AudioVector[MAXLINES];
|
||||||
|
extern Byte *rom;
|
||||||
|
extern Byte *megarom;
|
||||||
|
|
||||||
|
extern int frame;
|
||||||
|
extern int key2[128];
|
||||||
|
extern int key2vcnt;
|
||||||
|
extern unsigned long clk_counter;
|
||||||
|
|
||||||
|
extern int enahirq;
|
||||||
|
extern int pendirq;
|
||||||
|
extern int useforen;
|
||||||
|
extern long regionoff;
|
||||||
|
extern int sproff;
|
||||||
|
extern int tweakedaudio;
|
||||||
|
|
||||||
|
Byte read_P2(void);
|
||||||
|
int snapline(int pos, Byte reg, int t);
|
||||||
|
void ext_write(Byte dat, ADDRESS adr);
|
||||||
|
Byte ext_read(ADDRESS adr);
|
||||||
|
void handle_vbl(void);
|
||||||
|
void handle_evbl(void);
|
||||||
|
void handle_evbll(void);
|
||||||
|
Byte in_bus(void);
|
||||||
|
void write_p1(Byte d);
|
||||||
|
Byte read_t1(void);
|
||||||
|
void init_system(void);
|
||||||
|
void init_roms(void);
|
||||||
|
void run(void);
|
||||||
|
|
||||||
|
extern struct resource {
|
||||||
|
int bank;
|
||||||
|
int speed;
|
||||||
|
int voice;
|
||||||
|
int exrom;
|
||||||
|
int three_k;
|
||||||
|
int euro;
|
||||||
|
int openb;
|
||||||
|
int megaxrom;
|
||||||
|
int vpp;
|
||||||
|
int bios;
|
||||||
|
uint32_t crc;
|
||||||
|
int scoretype;
|
||||||
|
int scoreaddress;
|
||||||
|
int default_highscore;
|
||||||
|
} app_data;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VMACHINE_H */
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* O2 Voice emulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "vmachine.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "voice.h"
|
||||||
|
|
||||||
|
//static SAMPLE *voices[9][128];
|
||||||
|
static int voice_bank = 0;
|
||||||
|
static int voice_num = -1;
|
||||||
|
static int voice_addr = 0;
|
||||||
|
static int voice_ok = 0;
|
||||||
|
static int voice_st = 0;
|
||||||
|
static unsigned long clk_voice_start = 0;
|
||||||
|
|
||||||
|
void load_voice_samples(char *path)
|
||||||
|
{
|
||||||
|
/*int bank, sam, i, ld = 0;
|
||||||
|
char name[MAXC];
|
||||||
|
SAMPLE *sp = NULL;
|
||||||
|
|
||||||
|
printf("Loading voice samples... ");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
for (i = 0; i < 9; i++) {
|
||||||
|
for (sam = 0; sam < 128; sam++) {
|
||||||
|
if (i)
|
||||||
|
bank = 0xE8 + i - 1;
|
||||||
|
else
|
||||||
|
bank = 0xE4;
|
||||||
|
sprintf(name, "%svoice/%02x%02x.wav", path, bank, sam + 0x80);
|
||||||
|
|
||||||
|
voices[i][sam] = load_sample(name);
|
||||||
|
|
||||||
|
if (!voices[i][sam]) {
|
||||||
|
sprintf(name, "%svoice/%02X%02X.WAV", path, bank, sam + 0x80);
|
||||||
|
voices[i][sam] = load_sample(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voices[i][sam]) {
|
||||||
|
ld++;
|
||||||
|
if (!sp)
|
||||||
|
sp = voices[i][sam];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%d samples loaded\n", ld);
|
||||||
|
|
||||||
|
if (ld > 0) {
|
||||||
|
voice_num = allocate_voice(sp);
|
||||||
|
if (voice_num != -1)
|
||||||
|
voice_ok = 1;
|
||||||
|
else {
|
||||||
|
printf(" ERROR: could not allocate sound card voice\n");
|
||||||
|
voice_ok = 0;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_voice(void)
|
||||||
|
{
|
||||||
|
/*if (!voice_ok)
|
||||||
|
return;
|
||||||
|
if (voice_st == 2) {
|
||||||
|
if (voice_get_position(voice_num) < 0) {
|
||||||
|
if ((voice_bank >= 0) && (voice_bank < 9) && (voice_addr >= 0x80)
|
||||||
|
&& (voice_addr <= 0xff)) {
|
||||||
|
if (voices[voice_bank][voice_addr - 0x80]) {
|
||||||
|
reallocate_voice(voice_num,
|
||||||
|
voices[voice_bank][voice_addr - 0x80]);
|
||||||
|
voice_set_volume(voice_num, (255 * app_data.vvolume) / 100);
|
||||||
|
voice_start(voice_num);
|
||||||
|
clk_voice_start = clk_counter;
|
||||||
|
voice_st = 1;
|
||||||
|
} else {
|
||||||
|
voice_st = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (voice_st == 1) {
|
||||||
|
if ((voice_get_position(voice_num) < 0)
|
||||||
|
|| (clk_counter - clk_voice_start > 20)) {
|
||||||
|
voice_st = 0;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger_voice(int addr)
|
||||||
|
{
|
||||||
|
/*if (voice_ok) {
|
||||||
|
if (voice_st)
|
||||||
|
update_voice();
|
||||||
|
if ((voice_st == 0) && (voice_bank >= 0) && (voice_bank < 9)
|
||||||
|
&& (addr >= 0x80) && (addr <= 0xff)) {
|
||||||
|
voice_addr = addr;
|
||||||
|
voice_st = 2;
|
||||||
|
update_voice();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_voice_bank(int bank)
|
||||||
|
{
|
||||||
|
/*if (!voice_ok)
|
||||||
|
return;
|
||||||
|
if ((bank >= 0) && (bank <= 8))
|
||||||
|
voice_bank = bank;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_voice_status(void)
|
||||||
|
{
|
||||||
|
/*if (voice_ok) {
|
||||||
|
update_voice();
|
||||||
|
if (voice_st)
|
||||||
|
return 1;
|
||||||
|
}*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_voice(void)
|
||||||
|
{
|
||||||
|
/*if (voice_ok) {
|
||||||
|
voice_stop(voice_num);
|
||||||
|
voice_bank = 0;
|
||||||
|
voice_addr = 0;
|
||||||
|
voice_st = 0;
|
||||||
|
}*/
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef __VOICE_H
|
||||||
|
#define __VOICE_H
|
||||||
|
|
||||||
|
void load_voice_samples(char *path);
|
||||||
|
void update_voice(void);
|
||||||
|
void trigger_voice(int addr);
|
||||||
|
void reset_voice(void);
|
||||||
|
void set_voice_bank(int bank);
|
||||||
|
int get_voice_status(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,588 @@
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Videopac+ G7400 emulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "types.h"
|
||||||
|
#include "vmachine.h"
|
||||||
|
#include "vdc.h"
|
||||||
|
#include "vpp_cset.h"
|
||||||
|
#include "vpp.h"
|
||||||
|
#include "bitmap.h"
|
||||||
|
|
||||||
|
static void vpp_draw_char(int x, int y, Byte ch, Byte c0, Byte c1, Byte ext,
|
||||||
|
Byte dw, Byte dh, Byte ul);
|
||||||
|
static void vpp_update_screen(void);
|
||||||
|
|
||||||
|
static Byte LumReg = 0xff, TraReg = 0xff;
|
||||||
|
static Byte *colplus = NULL;
|
||||||
|
static int vppon = 1;
|
||||||
|
static int vpp_cx = 0;
|
||||||
|
static int vpp_cy = 0;
|
||||||
|
static Byte vpp_data = 0;
|
||||||
|
static int inc_curs = 1;
|
||||||
|
static int slice = 0;
|
||||||
|
static int vpp_y0 = 0;
|
||||||
|
static Byte vpp_r = 0;
|
||||||
|
Byte dchars[2][960];
|
||||||
|
Byte vpp_mem[40][32][4];
|
||||||
|
static int frame_cnt = 0;
|
||||||
|
static int blink_st = 0;
|
||||||
|
static int slicemode = 0;
|
||||||
|
static int need_update = 0;
|
||||||
|
static Bitmap* vppbmp;
|
||||||
|
|
||||||
|
Byte read_PB(Byte p)
|
||||||
|
{
|
||||||
|
p &= 0x3;
|
||||||
|
switch (p)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return LumReg >> 4;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return LumReg & 0xf;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return TraReg >> 4;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return TraReg & 0xf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_PB(Byte p, Byte val)
|
||||||
|
{
|
||||||
|
p &= 0x3;
|
||||||
|
val &= 0xf;
|
||||||
|
|
||||||
|
switch (p)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
LumReg = (val << 4) | (LumReg & 0xf);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
LumReg = (LumReg & 0xf0) | val;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
TraReg = (val << 4) | (TraReg & 0xf);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
TraReg = (TraReg & 0xf0) | val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
need_update = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte vpp_read(ADDRESS adr)
|
||||||
|
{
|
||||||
|
Byte t;
|
||||||
|
static Byte ta = 0;
|
||||||
|
static Byte tb = 0;
|
||||||
|
|
||||||
|
switch (adr)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
return ta;
|
||||||
|
case 5:
|
||||||
|
/* get return value from last read */
|
||||||
|
t = tb;
|
||||||
|
/* the real VPP starts a read cycle,
|
||||||
|
* the data gets returned at next read */
|
||||||
|
if (slicemode)
|
||||||
|
{
|
||||||
|
Byte ext, chr;
|
||||||
|
chr = vpp_mem[vpp_cx][vpp_cy][0];
|
||||||
|
ext = (vpp_mem[vpp_cx][vpp_cy][1] & 0x80) ? 1 : 0;
|
||||||
|
if (chr < 0xA0)
|
||||||
|
{
|
||||||
|
ta = 0;
|
||||||
|
fprintf(stderr, "unsupported: CHARROM read %d %d %d\n", chr,
|
||||||
|
ext, slice);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ta = dchars[ext][(chr - 0xA0) * 10 + slice];
|
||||||
|
ta = ((ta & 0x80) >> 7) | ((ta & 0x40) >> 5) | ((ta & 0x20) >> 3) | ((ta & 0x10) >> 1) | ((ta & 0x08) << 1) | ((ta & 0x04) << 3) | ((ta & 0x02) << 5) | ((ta & 0x01) << 7);
|
||||||
|
}
|
||||||
|
tb = 0xff; /* real VPP seems to return junk */
|
||||||
|
slice = (slice + 1) % 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ta = vpp_mem[vpp_cx][vpp_cy][1];
|
||||||
|
tb = vpp_mem[vpp_cx][vpp_cy][0];
|
||||||
|
if (inc_curs)
|
||||||
|
{
|
||||||
|
vpp_cx++;
|
||||||
|
if (vpp_cx >= 40)
|
||||||
|
{
|
||||||
|
vpp_cx = 0;
|
||||||
|
vpp_cy++;
|
||||||
|
if (vpp_cy >= 24)
|
||||||
|
vpp_cy = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
case 6:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpp_write(Byte dat, ADDRESS adr)
|
||||||
|
{
|
||||||
|
static Byte ta;
|
||||||
|
|
||||||
|
switch (adr)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (!slicemode)
|
||||||
|
vpp_mem[vpp_cx][vpp_cy][1] = dat;
|
||||||
|
else
|
||||||
|
ta = dat;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (slicemode)
|
||||||
|
{
|
||||||
|
Byte ext, chr;
|
||||||
|
chr = vpp_mem[vpp_cx][vpp_cy][0];
|
||||||
|
ext = (vpp_mem[vpp_cx][vpp_cy][1] & 0x80) ? 1 : 0;
|
||||||
|
if (chr >= 0xA0)
|
||||||
|
dchars[ext][(chr - 0xA0) * 10 + slice] = ((ta & 0x80) >> 7) | ((ta & 0x40) >> 5) | ((ta & 0x20) >> 3) | ((ta & 0x10) >> 1) | ((ta & 0x08) << 1) | ((ta & 0x04) << 3) | ((ta & 0x02) << 5) | ((ta & 0x01) << 7);
|
||||||
|
slice = (slice + 1) % 10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vpp_mem[vpp_cx][vpp_cy][0] = dat;
|
||||||
|
if ((dat > 0x7f) && (dat < 0xa0) && (!(vpp_mem[vpp_cx][vpp_cy][1] & 0x80)))
|
||||||
|
{
|
||||||
|
vpp_mem[vpp_cx][vpp_cy][2] = dat;
|
||||||
|
vpp_mem[vpp_cx][vpp_cy][3] = vpp_mem[vpp_cx][vpp_cy][1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vpp_mem[vpp_cx][vpp_cy][2] = vpp_mem[vpp_cx][vpp_cy][3] = 0;
|
||||||
|
}
|
||||||
|
if (inc_curs)
|
||||||
|
{
|
||||||
|
vpp_cx++;
|
||||||
|
if (vpp_cx >= 40)
|
||||||
|
{
|
||||||
|
vpp_cx = 0;
|
||||||
|
vpp_cy++;
|
||||||
|
if (vpp_cy >= 24)
|
||||||
|
vpp_cy = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
vpp_data = dat;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
switch (dat & 0xe0)
|
||||||
|
{
|
||||||
|
case 0x00: /* plus_cmd_brow */
|
||||||
|
vpp_cy = vpp_data & 0x1f;
|
||||||
|
vpp_cx = 0;
|
||||||
|
break;
|
||||||
|
case 0x20: /* plus_cmd_loady */
|
||||||
|
vpp_cy = vpp_data & 0x1f;
|
||||||
|
break;
|
||||||
|
case 0x40: /* plus_cmd_loadx */
|
||||||
|
vpp_cx = (vpp_data & 0x3f) % 40;
|
||||||
|
break;
|
||||||
|
case 0x60: /* plus_cmd_incc */
|
||||||
|
vpp_cx++;
|
||||||
|
if (vpp_cx >= 40)
|
||||||
|
{
|
||||||
|
vpp_cx = 0;
|
||||||
|
vpp_cy++;
|
||||||
|
if (vpp_cy >= 24)
|
||||||
|
vpp_cy = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x80: /* plus_cmd_loadm */
|
||||||
|
slicemode = 0;
|
||||||
|
slice = (vpp_data & 0x1f) % 10;
|
||||||
|
switch (vpp_data & 0xe0)
|
||||||
|
{
|
||||||
|
case 0x00: /* plus_loadm_wr */
|
||||||
|
inc_curs = 1;
|
||||||
|
break;
|
||||||
|
case 0x20: /* plus_loadm_rd */
|
||||||
|
inc_curs = 1;
|
||||||
|
break;
|
||||||
|
case 0x40: /* plus_loadm_wrni */
|
||||||
|
inc_curs = 0;
|
||||||
|
break;
|
||||||
|
case 0x60: /* plus_loadm_rdni */
|
||||||
|
inc_curs = 0;
|
||||||
|
break;
|
||||||
|
case 0x80: /* plus_loadm_wrsl */
|
||||||
|
slicemode = 1;
|
||||||
|
break;
|
||||||
|
case 0xA0: /* plus_loadm_rdsl */
|
||||||
|
slicemode = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xA0: /* plus_cmd_loadr */
|
||||||
|
vpp_r = vpp_data;
|
||||||
|
break;
|
||||||
|
case 0xC0: /* plus_cmd_loady0 */
|
||||||
|
if (vpp_data & 0x20)
|
||||||
|
fprintf(stderr, "unsupported: global double height");
|
||||||
|
vpp_y0 = (vpp_data & 0x1f) % 24;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
need_update = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpp_finish_bmp(Byte *vmem, int offx, int offy, int w, int h, int totw,
|
||||||
|
int toth)
|
||||||
|
{
|
||||||
|
int i, x, y, t, c, nc, clrx, clry;
|
||||||
|
int tcol[16], m[8] = {0x01, 0x10, 0x04, 0x40, 0x02, 0x20, 0x08, 0x80};
|
||||||
|
Byte *pnt, *pnt2, *pnt3;
|
||||||
|
|
||||||
|
if (vppon)
|
||||||
|
{
|
||||||
|
memset(colplus, 0, BMPW * BMPH);
|
||||||
|
vppon = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TraReg == 0xff)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vppon = 1;
|
||||||
|
|
||||||
|
frame_cnt--;
|
||||||
|
if (frame_cnt <= 0)
|
||||||
|
{
|
||||||
|
frame_cnt = 100;
|
||||||
|
blink_st = 1 - blink_st;
|
||||||
|
need_update = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_update)
|
||||||
|
vpp_update_screen();
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
tcol[i] = tcol[i + 8] = !(TraReg & m[i]);
|
||||||
|
|
||||||
|
if (w > totw - offx)
|
||||||
|
w = totw - offx;
|
||||||
|
if (h > toth - offy)
|
||||||
|
h = toth - offy;
|
||||||
|
|
||||||
|
if (w > vppbmp->w)
|
||||||
|
w = vppbmp->w;
|
||||||
|
if (h > vppbmp->h)
|
||||||
|
h = vppbmp->h;
|
||||||
|
|
||||||
|
clrx = clry = 0;
|
||||||
|
for (i = 0; (!clrx) && (i < totw); i++)
|
||||||
|
if (tcol[vmem[offy * totw + i] & 7])
|
||||||
|
clrx = 1;
|
||||||
|
for (i = 0; (!clry) && (i < toth); i++)
|
||||||
|
if (tcol[vmem[i * totw + offx] & 7])
|
||||||
|
clry = 1;
|
||||||
|
if (clrx)
|
||||||
|
for (y = 0; y < offy; y++)
|
||||||
|
for (x = 0; x < totw; x++)
|
||||||
|
vmem[y * totw + x] = 0;
|
||||||
|
if (clry)
|
||||||
|
for (y = 0; y < toth; y++)
|
||||||
|
for (x = 0; x < offx; x++)
|
||||||
|
vmem[y * totw + x] = 0;
|
||||||
|
|
||||||
|
for (y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
pnt = vmem + (offy + y) * totw + offx;
|
||||||
|
pnt2 = (Byte *)vppbmp->line[y];
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
while (x < w)
|
||||||
|
{
|
||||||
|
pnt3 = pnt;
|
||||||
|
c = *pnt++;
|
||||||
|
t = x++;
|
||||||
|
|
||||||
|
if ((((x + offx) & 3) == 0) && (sizeof(unsigned long) == 4))
|
||||||
|
{
|
||||||
|
unsigned long cccc, dddd, *p = (unsigned long *)pnt;
|
||||||
|
int t2 = x, w2 = w - 4;
|
||||||
|
cccc = (((unsigned long)c) & 0xff) | ((((unsigned long)c) & 0xff) << 8) | ((((unsigned long)c) & 0xff) << 16) | ((((unsigned long)c) & 0xff) << 24);
|
||||||
|
dddd = *p++;
|
||||||
|
while ((x < w2) && (dddd == cccc))
|
||||||
|
{
|
||||||
|
x += 4;
|
||||||
|
dddd = *p++;
|
||||||
|
}
|
||||||
|
pnt += x - t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c < 16)
|
||||||
|
{
|
||||||
|
if (tcol[c])
|
||||||
|
{
|
||||||
|
if (app_data.openb)
|
||||||
|
for (i = 0; i < x - t; i++)
|
||||||
|
*pnt3++ = *pnt2++ & 0xf;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(pnt3, pnt2, x - t);
|
||||||
|
pnt2 += x - t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < x - t; i++)
|
||||||
|
{
|
||||||
|
nc = *pnt2++;
|
||||||
|
if ((nc & 0x10) && app_data.openb)
|
||||||
|
{
|
||||||
|
*pnt3++ = nc & 0xf;
|
||||||
|
}
|
||||||
|
else if (nc & 8)
|
||||||
|
{
|
||||||
|
colplus[pnt3++ - vmem] = 0x40;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pnt3++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vpp_draw_char(int x, int y, Byte ch, Byte c0, Byte c1, Byte ext,
|
||||||
|
Byte dw, Byte dh, Byte ul)
|
||||||
|
{
|
||||||
|
int xx, yy, d, m, k;
|
||||||
|
|
||||||
|
if ((x > 39) || (y > 24) || (ext > 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
d = (dh == 2) ? 5 : 0;
|
||||||
|
|
||||||
|
for (yy = 0; yy < 10; yy++)
|
||||||
|
{
|
||||||
|
if (ul && (d == 9))
|
||||||
|
k = 255;
|
||||||
|
else if (ch >= 0xA0)
|
||||||
|
k = dchars[ext][(ch - 0xA0) * 10 + d];
|
||||||
|
else if (ch >= 0x80)
|
||||||
|
k = 255;
|
||||||
|
else
|
||||||
|
k = vpp_cset[ext][ch * 10 + d];
|
||||||
|
|
||||||
|
m = (dw == 2) ? 0x08 : 0x80;
|
||||||
|
|
||||||
|
for (xx = 0; xx < 8; xx++)
|
||||||
|
{
|
||||||
|
vppbmp->line[y * 10 + yy][x * 8 + xx] = (k & m) ? c1 : c0;
|
||||||
|
if ((xx % 2) || (dw == 0))
|
||||||
|
m >>= 1;
|
||||||
|
}
|
||||||
|
if ((yy % 2) || (dh == 0))
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vpp_update_screen(void)
|
||||||
|
{
|
||||||
|
int i, x, y, l, chr, attr, ext, c0, c1, dw, dh, hpar, vpar, lvd, lhd,
|
||||||
|
ser_chr, ser_atr, ul, conc, box, swapcol;
|
||||||
|
int tlum[8], m[8] = {0x01, 0x10, 0x04, 0x40, 0x02, 0x20, 0x08, 0x80};
|
||||||
|
|
||||||
|
clear(vppbmp);
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
tlum[i] = (LumReg & m[i]) ? 0 : 8;
|
||||||
|
|
||||||
|
vpar = lvd = 0;
|
||||||
|
for (y = 0; y < 25; y++)
|
||||||
|
{
|
||||||
|
|
||||||
|
vpar = (lvd == 0) ? 0 : 1 - vpar;
|
||||||
|
|
||||||
|
l = (y == 0) ? 31 : (y - 1 + vpp_y0) % 24;
|
||||||
|
c0 = ul = conc = box = 0;
|
||||||
|
|
||||||
|
hpar = lhd = 0;
|
||||||
|
for (x = 0; x < 40; x++)
|
||||||
|
{
|
||||||
|
hpar = (lhd == 0) ? 0 : 1 - hpar;
|
||||||
|
|
||||||
|
chr = vpp_mem[x][l][0];
|
||||||
|
attr = vpp_mem[x][l][1];
|
||||||
|
c1 = attr & 0x7;
|
||||||
|
c1 = ((c1 & 2) | ((c1 & 1) << 2) | ((c1 & 4) >> 2));
|
||||||
|
ext = (attr & 0x80) ? 1 : 0;
|
||||||
|
|
||||||
|
ser_chr = vpp_mem[x][l][2];
|
||||||
|
ser_atr = vpp_mem[x][l][3];
|
||||||
|
if (ser_chr)
|
||||||
|
{
|
||||||
|
c0 = (ser_atr >> 4) & 0x7;
|
||||||
|
c0 = ((c0 & 2) | ((c0 & 1) << 2) | ((c0 & 4) >> 2));
|
||||||
|
ul = ser_chr & 4;
|
||||||
|
conc = ser_chr & 1;
|
||||||
|
box = ser_chr & 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext)
|
||||||
|
{
|
||||||
|
c0 = (attr >> 4) & 0x7;
|
||||||
|
c0 = ((c0 & 2) | ((c0 & 1) << 2) | ((c0 & 4) >> 2));
|
||||||
|
dw = dh = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dw = (attr & 0x20) ? (hpar ? 2 : 1) : 0;
|
||||||
|
dh = (attr & 0x10) ? (vpar ? 2 : 1) : 0;
|
||||||
|
if (dw)
|
||||||
|
lhd = 1;
|
||||||
|
if (dh)
|
||||||
|
lvd = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapcol = 0;
|
||||||
|
|
||||||
|
/* cursor display */
|
||||||
|
if ((x == vpp_cx) && (l == vpp_cy))
|
||||||
|
{
|
||||||
|
/* on cursor position */
|
||||||
|
if (vpp_r & 0x10)
|
||||||
|
{
|
||||||
|
/* cursor display active */
|
||||||
|
swapcol = !swapcol;
|
||||||
|
if ((vpp_r & 0x80) && blink_st)
|
||||||
|
{
|
||||||
|
/* blinking active */
|
||||||
|
swapcol = !swapcol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invert attribute */
|
||||||
|
if ((!ext) && (attr & 0x40))
|
||||||
|
swapcol = !swapcol;
|
||||||
|
|
||||||
|
/* blinking chars */
|
||||||
|
if ((vpp_r & 0x80) && !(attr & 8) && !blink_st)
|
||||||
|
{
|
||||||
|
/* cursor handling is done already */
|
||||||
|
if (!(vpp_r & 0x10) || (x != vpp_cx) || (l != vpp_cy))
|
||||||
|
{
|
||||||
|
c1 = c0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((y == 0) && (vpp_r & 8)) || ((y != 0) && (vpp_r & 1)))
|
||||||
|
{
|
||||||
|
if ((!conc) || (!(vpp_r & 4)))
|
||||||
|
{
|
||||||
|
if (box || (!(vpp_r & 2)))
|
||||||
|
{
|
||||||
|
if (swapcol)
|
||||||
|
vpp_draw_char(x, y, chr, c1 | tlum[c1],
|
||||||
|
c0 | tlum[c0], ext, dw, dh, ul);
|
||||||
|
else
|
||||||
|
vpp_draw_char(x, y, chr, c0 | tlum[c0],
|
||||||
|
c1 | tlum[c1], ext, dw, dh, ul);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vpp_draw_char(x, y, 255, (app_data.openb) ? 16 : 0, 0,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vpp_r & 0x20)
|
||||||
|
{
|
||||||
|
for (y = vppbmp->h - 1; y >= 10; y--)
|
||||||
|
for (x = 0; x < vppbmp->w; x++)
|
||||||
|
vppbmp->line[y][x] = vppbmp->line[(y - 10) / 2 + 10][x];
|
||||||
|
}
|
||||||
|
|
||||||
|
need_update = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_colplus(Byte *col)
|
||||||
|
{
|
||||||
|
if (vppon)
|
||||||
|
memcpy(col, colplus, BMPW * BMPH);
|
||||||
|
else
|
||||||
|
memset(col, 0, BMPW * BMPH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_vpp(void)
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
if (!colplus)
|
||||||
|
colplus = (Byte *)malloc(BMPW * BMPH);
|
||||||
|
if (!vppbmp)
|
||||||
|
vppbmp = NewBitmap(BMPW, BMPH);
|
||||||
|
clear(vppbmp);
|
||||||
|
|
||||||
|
memset(colplus, 0, BMPW * BMPH);
|
||||||
|
|
||||||
|
LumReg = TraReg = 0xff;
|
||||||
|
vpp_cx = 0;
|
||||||
|
vpp_cy = 0;
|
||||||
|
vpp_y0 = 0;
|
||||||
|
vpp_r = 0;
|
||||||
|
inc_curs = 1;
|
||||||
|
vpp_data = 0;
|
||||||
|
frame_cnt = 0;
|
||||||
|
blink_st = 0;
|
||||||
|
slice = 0;
|
||||||
|
slicemode = 0;
|
||||||
|
need_update = 1;
|
||||||
|
vppon = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
for (j = 0; j < 960; j++)
|
||||||
|
dchars[i][j] = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 40; i++)
|
||||||
|
for (j = 0; j < 32; j++)
|
||||||
|
for (k = 0; k < 4; k++)
|
||||||
|
vpp_mem[i][j][k] = 0;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef __VPP_H
|
||||||
|
#define __VPP_H
|
||||||
|
|
||||||
|
Byte read_PB(Byte p);
|
||||||
|
void write_PB(Byte p, Byte val);
|
||||||
|
Byte vpp_read(ADDRESS adr);
|
||||||
|
void vpp_write(Byte dat, ADDRESS adr);
|
||||||
|
void vpp_finish_bmp(Byte *vmem, int offx, int offy, int w, int h, int totw, int toth);
|
||||||
|
void init_vpp(void);
|
||||||
|
void load_colplus(Byte *col);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,279 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
||||||
|
*
|
||||||
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
||||||
|
*
|
||||||
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
||||||
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* http://o2em.sourceforge.net
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Videopac+ character table
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "vpp_cset.h"
|
||||||
|
|
||||||
|
const Byte vpp_cset[2][1280] = {
|
||||||
|
{/* Alphanumeric */
|
||||||
|
0x00, 0x38, 0x44, 0x40, 0x20, 0x10, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x28, 0x00, 0x38, 0x44, 0x7c, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x10, 0x3c, 0x20, 0x30, 0x20, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x14, 0x10, 0x38, 0x10, 0x24, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x38, 0x50, 0x38, 0x14, 0x54, 0x38, 0x10, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x10, 0x20,
|
||||||
|
0x00, 0x28, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x28, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x18, 0x00, 0x38, 0x44, 0x7c, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x18, 0x00, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x08, 0x3c, 0x20, 0x30, 0x20, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x50, 0x50, 0x58, 0x50, 0x50, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x14, 0x3c, 0x20, 0x30, 0x20, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x10, 0x20, 0x7f, 0x20, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x00, 0x00, 0x08, 0x04, 0xfe, 0x04, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x00,
|
||||||
|
0x00, 0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x7c, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x10, 0x38, 0x44, 0x7c, 0x40, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x28, 0x00, 0x38, 0x44, 0x7c, 0x40, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x28, 0x00, 0x30, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x38, 0x40, 0x40, 0x40, 0x38, 0x10, 0x20,
|
||||||
|
0x00, 0x10, 0x28, 0x00, 0x44, 0x44, 0x4c, 0x34, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x10, 0x34, 0x4c, 0x44, 0x4c, 0x34, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x10, 0x00, 0x7c, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x10, 0x38, 0x44, 0x7c, 0x40, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x3c, 0x52, 0x5e, 0x50, 0x3e, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x28, 0x38, 0x44, 0x7c, 0x40, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0xc0, 0x40, 0x44, 0x4c, 0x14, 0x3e, 0x04, 0x00,
|
||||||
|
0x00, 0x40, 0xc0, 0x40, 0x4c, 0x52, 0x04, 0x08, 0x1e, 0x00,
|
||||||
|
0x00, 0xe0, 0x20, 0x40, 0x24, 0xcc, 0x14, 0x3e, 0x04, 0x00,
|
||||||
|
0x00, 0x10, 0x28, 0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x28, 0x00, 0x3c, 0x20, 0x30, 0x20, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x28, 0x34, 0x4c, 0x44, 0x4c, 0x34, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x64, 0x08, 0x10, 0x20, 0x4c, 0x0c, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x50, 0x50, 0x20, 0x54, 0x48, 0x34, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x54, 0x38, 0x10, 0x38, 0x54, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||||
|
0x01, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x80,
|
||||||
|
0x00, 0x10, 0x28, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x04, 0x18, 0x20, 0x40, 0x7c, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x04, 0x08, 0x18, 0x04, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x18, 0x28, 0x48, 0x7c, 0x08, 0x08, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x40, 0x78, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x20, 0x40, 0x78, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x04, 0x08, 0x10, 0x20, 0x20, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x44, 0x3c, 0x04, 0x04, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x20, 0x40, 0x00,
|
||||||
|
0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x04, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x5c, 0x54, 0x5c, 0x40, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x78, 0x44, 0x44, 0x78, 0x44, 0x44, 0x78, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x40, 0x40, 0x70, 0x40, 0x40, 0x7c, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x40, 0x40, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x40, 0x40, 0x4c, 0x44, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x48, 0x30, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x6c, 0x54, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x64, 0x54, 0x4c, 0x44, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x78, 0x44, 0x44, 0x78, 0x40, 0x40, 0x40, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x44, 0x44, 0x54, 0x48, 0x34, 0x00, 0x00,
|
||||||
|
0x00, 0x78, 0x44, 0x44, 0x78, 0x50, 0x48, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x44, 0x40, 0x38, 0x04, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x44, 0x54, 0x54, 0x54, 0x28, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x44, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7c, 0x00, 0x00,
|
||||||
|
0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00, 0x00,
|
||||||
|
0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x04, 0x02, 0x01,
|
||||||
|
0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x28, 0x00, 0x30, 0x10, 0x10, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x34, 0x4c, 0x44, 0x4c, 0x34, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0x40, 0x78, 0x44, 0x44, 0x44, 0x78, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x38, 0x40, 0x40, 0x40, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x04, 0x04, 0x3c, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x38, 0x44, 0x7c, 0x40, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x24, 0x20, 0x70, 0x20, 0x20, 0x20, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x3c, 0x44, 0x44, 0x3c, 0x04, 0x24, 0x18,
|
||||||
|
0x00, 0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x08, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x48, 0x30,
|
||||||
|
0x00, 0x20, 0x20, 0x24, 0x28, 0x30, 0x28, 0x24, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x68, 0x54, 0x54, 0x54, 0x54, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x78, 0x40, 0x40,
|
||||||
|
0x00, 0x00, 0x00, 0x3c, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x04,
|
||||||
|
0x00, 0x00, 0x00, 0x58, 0x64, 0x40, 0x40, 0x40, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x38, 0x40, 0x38, 0x04, 0x78, 0x00, 0x00,
|
||||||
|
0x00, 0x20, 0x20, 0x38, 0x20, 0x20, 0x20, 0x18, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x4c, 0x34, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x44, 0x44, 0x54, 0x54, 0x28, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x44, 0x44, 0x4c, 0x34, 0x04, 0x44, 0x38,
|
||||||
|
0x00, 0x00, 0x00, 0x7c, 0x08, 0x10, 0x20, 0x7c, 0x00, 0x00,
|
||||||
|
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||||
|
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
|
||||||
|
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||||
|
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||||
|
{/* Separated semi-graphic */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x70, 0x70, 0x70, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x70, 0x70, 0x70, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x70, 0x70, 0x70, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x07, 0x07, 0x07, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x07, 0x07, 0x07, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x07, 0x07, 0x07, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x77, 0x77, 0x77, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x77, 0x77, 0x77, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x70, 0x70, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x70, 0x70, 0x70, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x70, 0x70, 0x70, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x70, 0x70, 0x70, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x07, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x07, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x07, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x77, 0x77, 0x77, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x77, 0x77, 0x77, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x07, 0x07, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x70, 0x70, 0x70, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x70, 0x70, 0x70, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x70, 0x70, 0x70, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x70, 0x70, 0x70, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x07, 0x07, 0x07, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x07, 0x07, 0x07, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x07, 0x07, 0x07, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x70, 0x70, 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x07, 0x07, 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x00,
|
||||||
|
/* Mosaic semi-graphic */
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
|
||||||
|
0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef __VPP_CSET_H
|
||||||
|
#define __VPP_CSET_H
|
||||||
|
|
||||||
|
extern const Byte vpp_cset[2][1280];
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue